AndroidKeyStoreTest.java revision 8b58c52bf4cc276165b1857eb4087eabde7b6477
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_Success() throws Exception {
581        mKeyStore.load(null, null);
582
583        // Should not throw when a non-existent entry is requested for delete.
584        mKeyStore.deleteEntry(TEST_ALIAS_1);
585    }
586
587    public void testKeyStore_DeleteEntry_NonExistent_Success() throws Exception {
588        mKeyStore.load(null, null);
589
590        // TEST_ALIAS_1
591        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
592                FAKE_KEY_1));
593        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
594        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
595
596        // Should not throw when a non-existent entry is requested for delete.
597        mKeyStore.deleteEntry(TEST_ALIAS_2);
598    }
599
600    public void testKeyStore_GetCertificate_Single_Success() throws Exception {
601        mKeyStore.load(null, null);
602
603        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
604
605        assertAliases(new String[] { TEST_ALIAS_1 });
606
607        assertNull("Certificate should not exist in keystore",
608                mKeyStore.getCertificate(TEST_ALIAS_2));
609
610        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
611
612        assertNotNull("Retrieved certificate should not be null", retrieved);
613
614        CertificateFactory f = CertificateFactory.getInstance("X.509");
615        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
616
617        assertEquals("Actual and retrieved certificates should be the same", actual, retrieved);
618    }
619
620    public void testKeyStore_GetCertificate_NonExist_Failure() throws Exception {
621        mKeyStore.load(null, null);
622
623        assertNull("Certificate should not exist in keystore",
624                mKeyStore.getCertificate(TEST_ALIAS_1));
625    }
626
627    public void testKeyStore_GetCertificateAlias_CAEntry_Success() throws Exception {
628        mKeyStore.load(null, null);
629
630        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
631
632        CertificateFactory f = CertificateFactory.getInstance("X.509");
633        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
634
635        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
636                mKeyStore.getCertificateAlias(actual));
637    }
638
639    public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Success() throws Exception {
640        mKeyStore.load(null, null);
641
642        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
643                FAKE_KEY_1));
644        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
645        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
646
647        CertificateFactory f = CertificateFactory.getInstance("X.509");
648        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
649
650        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
651                mKeyStore.getCertificateAlias(actual));
652    }
653
654    public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Success()
655            throws Exception {
656        mKeyStore.load(null, null);
657
658        // Insert TrustedCertificateEntry with CA name
659        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
660
661        // Insert PrivateKeyEntry that uses the same CA
662        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
663                FAKE_KEY_1));
664        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
665        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
666
667        CertificateFactory f = CertificateFactory.getInstance("X.509");
668        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
669
670        assertEquals("Stored certificate alias should be found", TEST_ALIAS_2,
671                mKeyStore.getCertificateAlias(actual));
672    }
673
674    public void testKeyStore_GetCertificateAlias_NonExist_Empty_Failure() throws Exception {
675        mKeyStore.load(null, null);
676
677        CertificateFactory f = CertificateFactory.getInstance("X.509");
678        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
679
680        assertNull("Stored certificate alias should not be found",
681                mKeyStore.getCertificateAlias(actual));
682    }
683
684    public void testKeyStore_GetCertificateAlias_NonExist_Failure() throws Exception {
685        mKeyStore.load(null, null);
686
687        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
688
689        CertificateFactory f = CertificateFactory.getInstance("X.509");
690        Certificate userCert = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
691
692        assertNull("Stored certificate alias should be found",
693                mKeyStore.getCertificateAlias(userCert));
694    }
695
696    public void testKeyStore_GetCertificateChain_SingleLength_Success() throws Exception {
697        mKeyStore.load(null, null);
698
699        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
700                FAKE_KEY_1));
701        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
702        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
703
704        CertificateFactory cf = CertificateFactory.getInstance("X.509");
705        Certificate[] expected = new Certificate[2];
706        expected[0] = cf.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
707        expected[1] = cf.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
708
709        Certificate[] actual = mKeyStore.getCertificateChain(TEST_ALIAS_1);
710
711        assertNotNull("Returned certificate chain should not be null", actual);
712        assertEquals("Returned certificate chain should be correct size", expected.length,
713                actual.length);
714        assertEquals("First certificate should be user certificate", expected[0], actual[0]);
715        assertEquals("Second certificate should be CA certificate", expected[1], actual[1]);
716
717        // Negative test when keystore is populated.
718        assertNull("Stored certificate alias should not be found",
719                mKeyStore.getCertificateChain(TEST_ALIAS_2));
720    }
721
722    public void testKeyStore_GetCertificateChain_NonExist_Failure() throws Exception {
723        mKeyStore.load(null, null);
724
725        assertNull("Stored certificate alias should not be found",
726                mKeyStore.getCertificateChain(TEST_ALIAS_1));
727    }
728
729    public void testKeyStore_GetCreationDate_PrivateKeyEntry_Success() throws Exception {
730        mKeyStore.load(null, null);
731
732        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
733                FAKE_KEY_1));
734        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
735        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
736
737        Date now = new Date();
738        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
739
740        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
741        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
742
743        assertTrue("Time should be close to current time", actual.before(expectedBefore));
744        assertTrue("Time should be close to current time", actual.after(expectedAfter));
745    }
746
747    public void testKeyStore_GetCreationDate_CAEntry_Success() throws Exception {
748        mKeyStore.load(null, null);
749
750        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
751
752        Date now = new Date();
753        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
754        assertNotNull("Certificate should be found", actual);
755
756        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
757        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
758
759        assertTrue("Time should be close to current time", actual.before(expectedBefore));
760        assertTrue("Time should be close to current time", actual.after(expectedAfter));
761    }
762
763    public void testKeyStore_GetEntry_NullParams_Success() throws Exception {
764        mKeyStore.load(null, null);
765
766        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
767                FAKE_KEY_1));
768        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
769        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
770
771        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
772        assertNotNull("Entry should exist", entry);
773
774        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
775
776        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
777
778        assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
779    }
780
781    @SuppressWarnings("unchecked")
782    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, byte[] key, byte[] cert,
783            byte[] ca) throws Exception {
784        KeyFactory keyFact = KeyFactory.getInstance("RSA");
785        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(key));
786
787        CertificateFactory certFact = CertificateFactory.getInstance("X.509");
788        Certificate expectedCert = certFact.generateCertificate(new ByteArrayInputStream(cert));
789
790        final Collection<Certificate> expectedChain;
791        if (ca != null) {
792            expectedChain = (Collection<Certificate>) certFact
793                    .generateCertificates(new ByteArrayInputStream(ca));
794        } else {
795            expectedChain = null;
796        }
797
798        assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, expectedChain);
799    }
800
801    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey,
802            Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception {
803        assertEquals("Returned PrivateKey should be what we inserted", expectedKey,
804                keyEntry.getPrivateKey());
805
806        assertEquals("Returned Certificate should be what we inserted", expectedCert,
807                keyEntry.getCertificate());
808
809        Certificate[] actualChain = keyEntry.getCertificateChain();
810
811        assertEquals("First certificate in chain should be user cert", expectedCert, actualChain[0]);
812
813        if (expectedChain == null) {
814            assertEquals("Certificate chain should not include CAs", 1, actualChain.length);
815        } else {
816            int i = 1;
817            final Iterator<Certificate> it = expectedChain.iterator();
818            while (it.hasNext()) {
819                assertEquals("CA chain certificate should equal what we put in", it.next(),
820                        actualChain[i++]);
821            }
822        }
823    }
824
825    public void testKeyStore_GetEntry_Nonexistent_NullParams_Failure() throws Exception {
826        mKeyStore.load(null, null);
827
828        assertNull("A non-existent entry should return null",
829                mKeyStore.getEntry(TEST_ALIAS_1, null));
830    }
831
832    public void testKeyStore_GetKey_NoPassword_Success() throws Exception {
833        mKeyStore.load(null, null);
834
835        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
836                FAKE_KEY_1));
837        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
838        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
839
840        Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
841        assertNotNull("Key should exist", key);
842
843        assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey);
844
845        RSAPrivateKey actualKey = (RSAPrivateKey) key;
846
847        KeyFactory keyFact = KeyFactory.getInstance("RSA");
848        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
849
850        assertEquals("Inserted key should be same as retrieved key", actualKey, expectedKey);
851    }
852
853    public void testKeyStore_GetKey_Certificate_Failure() throws Exception {
854        mKeyStore.load(null, null);
855
856        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
857
858        assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
859    }
860
861    public void testKeyStore_GetKey_NonExistent_Failure() throws Exception {
862        mKeyStore.load(null, null);
863
864        assertNull("A non-existent entry should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
865    }
866
867    public void testKeyStore_GetProvider_Success() throws Exception {
868        assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
869    }
870
871    public void testKeyStore_GetType_Success() throws Exception {
872        assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
873    }
874
875    public void testKeyStore_IsCertificateEntry_CA_Success() throws Exception {
876        mKeyStore.load(null, null);
877
878        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
879
880        assertTrue("Should return true for CA certificate",
881                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
882    }
883
884    public void testKeyStore_IsCertificateEntry_PrivateKey_Failure() throws Exception {
885        mKeyStore.load(null, null);
886
887        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
888                FAKE_KEY_1));
889        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
890        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
891
892        assertFalse("Should return false for PrivateKeyEntry",
893                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
894    }
895
896    public void testKeyStore_IsCertificateEntry_NonExist_Failure() throws Exception {
897        mKeyStore.load(null, null);
898
899        assertFalse("Should return false for non-existent entry",
900                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
901    }
902
903    public void testKeyStore_IsKeyEntry_PrivateKey_Success() throws Exception {
904        mKeyStore.load(null, null);
905
906        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
907                FAKE_KEY_1));
908        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
909        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
910
911        assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1));
912    }
913
914    public void testKeyStore_IsKeyEntry_CA_Failure() throws Exception {
915        mKeyStore.load(null, null);
916
917        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
918
919        assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1));
920    }
921
922    public void testKeyStore_IsKeyEntry_NonExist_Failure() throws Exception {
923        mKeyStore.load(null, null);
924
925        assertFalse("Should return false for non-existent entry",
926                mKeyStore.isKeyEntry(TEST_ALIAS_1));
927    }
928
929    public void testKeyStore_SetCertificate_CA_Success() throws Exception {
930        final CertificateFactory f = CertificateFactory.getInstance("X.509");
931        final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
932
933        mKeyStore.load(null, null);
934
935        mKeyStore.setCertificateEntry(TEST_ALIAS_1, actual);
936        assertAliases(new String[] { TEST_ALIAS_1 });
937
938        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
939
940        assertEquals("Retrieved certificate should be the same as the one inserted", actual,
941                retrieved);
942    }
943
944    public void testKeyStore_SetCertificate_CAExists_Overwrite_Success() throws Exception {
945        mKeyStore.load(null, null);
946
947        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
948
949        assertAliases(new String[] { TEST_ALIAS_1 });
950
951        final CertificateFactory f = CertificateFactory.getInstance("X.509");
952        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
953
954        // TODO have separate FAKE_CA for second test
955        mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
956
957        assertAliases(new String[] { TEST_ALIAS_1 });
958    }
959
960    public void testKeyStore_SetCertificate_PrivateKeyExists_Failure() throws Exception {
961        mKeyStore.load(null, null);
962
963        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
964                FAKE_KEY_1));
965        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
966        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
967
968        assertAliases(new String[] { TEST_ALIAS_1 });
969
970        final CertificateFactory f = CertificateFactory.getInstance("X.509");
971        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
972
973        try {
974            mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
975            fail("Should throw when trying to overwrite a PrivateKey entry with a Certificate");
976        } catch (KeyStoreException success) {
977        }
978    }
979
980    public void testKeyStore_SetEntry_PrivateKeyEntry_Success() throws Exception {
981        mKeyStore.load(null, null);
982
983        KeyFactory keyFact = KeyFactory.getInstance("RSA");
984        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
985
986        final CertificateFactory f = CertificateFactory.getInstance("X.509");
987
988        final Certificate[] expectedChain = new Certificate[2];
989        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
990        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
991
992        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
993
994        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
995
996        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
997        assertNotNull("Retrieved entry should exist", actualEntry);
998
999        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1000                actualEntry instanceof PrivateKeyEntry);
1001
1002        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1003
1004        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1005    }
1006
1007    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Success()
1008            throws Exception {
1009        mKeyStore.load(null, null);
1010
1011        final KeyFactory keyFact = KeyFactory.getInstance("RSA");
1012        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1013
1014        // Start with PrivateKeyEntry
1015        {
1016            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1017
1018            final Certificate[] expectedChain = new Certificate[2];
1019            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1020            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1021
1022            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1023
1024            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1025
1026            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1027            assertNotNull("Retrieved entry should exist", actualEntry);
1028
1029            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1030                    actualEntry instanceof PrivateKeyEntry);
1031
1032            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1033
1034            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1035        }
1036
1037        // TODO make entirely new test vector for the overwrite
1038        // Replace with PrivateKeyEntry
1039        {
1040            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1041
1042            final Certificate[] expectedChain = new Certificate[2];
1043            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1044            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1045
1046            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1047
1048            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1049
1050            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1051            assertNotNull("Retrieved entry should exist", actualEntry);
1052
1053            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1054                    actualEntry instanceof PrivateKeyEntry);
1055
1056            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1057
1058            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1059        }
1060    }
1061
1062    public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Success() throws Exception {
1063        mKeyStore.load(null, null);
1064
1065        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1066
1067        // Start with TrustedCertificateEntry
1068        {
1069            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1070
1071            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1072            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1073
1074            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1075            assertNotNull("Retrieved entry should exist", actualEntry);
1076            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1077                    actualEntry instanceof TrustedCertificateEntry);
1078            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1079            assertEquals("Stored and retrieved certificates should be the same",
1080                    expectedCertEntry.getTrustedCertificate(),
1081                    actualCertEntry.getTrustedCertificate());
1082        }
1083
1084        // Replace with PrivateKeyEntry
1085        {
1086            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1087            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1088            final Certificate[] expectedChain = new Certificate[2];
1089            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1090            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1091
1092            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1093
1094            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1095
1096            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1097            assertNotNull("Retrieved entry should exist", actualEntry);
1098            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1099                    actualEntry instanceof PrivateKeyEntry);
1100
1101            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1102            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1103        }
1104    }
1105
1106    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Success() throws Exception {
1107        mKeyStore.load(null, null);
1108
1109        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1110
1111        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1112
1113        // Start with PrivateKeyEntry
1114        {
1115            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1116            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1117            final Certificate[] expectedChain = new Certificate[2];
1118            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1119            expectedChain[1] = caCert;
1120
1121            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1122
1123            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1124
1125            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1126            assertNotNull("Retrieved entry should exist", actualEntry);
1127            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1128                    actualEntry instanceof PrivateKeyEntry);
1129
1130            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1131            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1132        }
1133
1134        // Replace with TrustedCertificateEntry
1135        {
1136            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1137            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1138
1139            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1140            assertNotNull("Retrieved entry should exist", actualEntry);
1141            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1142                    actualEntry instanceof TrustedCertificateEntry);
1143            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1144            assertEquals("Stored and retrieved certificates should be the same",
1145                    expectedCertEntry.getTrustedCertificate(),
1146                    actualCertEntry.getTrustedCertificate());
1147        }
1148    }
1149
1150    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Success()
1151            throws Exception {
1152        mKeyStore.load(null, null);
1153
1154        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1155
1156        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1157
1158        // Start with PrivateKeyEntry
1159        {
1160            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1161            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1162            final Certificate[] expectedChain = new Certificate[2];
1163            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1164            expectedChain[1] = caCert;
1165
1166            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1167
1168            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1169
1170            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1171            assertNotNull("Retrieved entry should exist", actualEntry);
1172            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1173                    actualEntry instanceof PrivateKeyEntry);
1174
1175            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1176            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1177        }
1178
1179        // Replace with PrivateKeyEntry that has no chain
1180        {
1181            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1182            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1183            final Certificate[] expectedChain = new Certificate[1];
1184            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1185
1186            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1187
1188            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1189
1190            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1191            assertNotNull("Retrieved entry should exist", actualEntry);
1192            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1193                    actualEntry instanceof PrivateKeyEntry);
1194
1195            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1196            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, null);
1197        }
1198    }
1199
1200    public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Success() throws Exception {
1201        mKeyStore.load(null, null);
1202
1203        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1204
1205        // Insert TrustedCertificateEntry
1206        {
1207            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1208
1209            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1210            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1211
1212            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1213            assertNotNull("Retrieved entry should exist", actualEntry);
1214            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1215                    actualEntry instanceof TrustedCertificateEntry);
1216            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1217            assertEquals("Stored and retrieved certificates should be the same",
1218                    expectedCertEntry.getTrustedCertificate(),
1219                    actualCertEntry.getTrustedCertificate());
1220        }
1221
1222        // Replace with TrustedCertificateEntry of USER
1223        {
1224            final Certificate userCert = f
1225                    .generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1226
1227            TrustedCertificateEntry expectedUserEntry = new TrustedCertificateEntry(userCert);
1228            mKeyStore.setEntry(TEST_ALIAS_1, expectedUserEntry, null);
1229
1230            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1231            assertNotNull("Retrieved entry should exist", actualEntry);
1232            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1233                    actualEntry instanceof TrustedCertificateEntry);
1234            TrustedCertificateEntry actualUserEntry = (TrustedCertificateEntry) actualEntry;
1235            assertEquals("Stored and retrieved certificates should be the same",
1236                    expectedUserEntry.getTrustedCertificate(),
1237                    actualUserEntry.getTrustedCertificate());
1238        }
1239    }
1240
1241    public void testKeyStore_SetKeyEntry_ProtectedKey_Failure() throws Exception {
1242        mKeyStore.load(null, null);
1243
1244        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1245
1246        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1247
1248        KeyFactory keyFact = KeyFactory.getInstance("RSA");
1249        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1250        final Certificate[] chain = new Certificate[2];
1251        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1252        chain[1] = caCert;
1253
1254        try {
1255            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, "foo".toCharArray(), chain);
1256            fail("Should fail when a password is specified");
1257        } catch (KeyStoreException success) {
1258        }
1259    }
1260
1261    public void testKeyStore_SetKeyEntry_Success() throws Exception {
1262        mKeyStore.load(null, null);
1263
1264        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1265
1266        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1267
1268        KeyFactory keyFact = KeyFactory.getInstance("RSA");
1269        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1270        final Certificate[] chain = new Certificate[2];
1271        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1272        chain[1] = caCert;
1273
1274        mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1275
1276        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1277        assertNotNull("Retrieved entry should exist", actualEntry);
1278
1279        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1280                actualEntry instanceof PrivateKeyEntry);
1281
1282        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1283
1284        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1285    }
1286
1287    public void testKeyStore_SetKeyEntry_Replaced_Success() throws Exception {
1288        mKeyStore.load(null, null);
1289
1290        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1291
1292        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1293
1294        // Insert initial key
1295        {
1296            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1297            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1298            final Certificate[] chain = new Certificate[2];
1299            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1300            chain[1] = caCert;
1301
1302            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1303
1304            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1305            assertNotNull("Retrieved entry should exist", actualEntry);
1306
1307            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1308                    actualEntry instanceof PrivateKeyEntry);
1309
1310            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1311
1312            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1313        }
1314
1315        // TODO make a separate key
1316        // Replace key
1317        {
1318            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1319            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1320            final Certificate[] chain = new Certificate[2];
1321            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1322            chain[1] = caCert;
1323
1324            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1325
1326            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1327            assertNotNull("Retrieved entry should exist", actualEntry);
1328
1329            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1330                    actualEntry instanceof PrivateKeyEntry);
1331
1332            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1333
1334            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1335        }
1336    }
1337
1338    @SuppressWarnings("deprecation")
1339    private static X509Certificate generateCertificate(android.security.KeyStore keyStore,
1340            String alias, BigInteger serialNumber, X500Principal subjectDN, Date notBefore,
1341            Date notAfter) throws Exception {
1342        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
1343
1344        final PrivateKey privKey;
1345        final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore");
1346        try {
1347            privKey = engine.getPrivateKeyById(privateKeyAlias);
1348        } catch (InvalidKeyException e) {
1349            throw new RuntimeException("Can't get key", e);
1350        }
1351
1352        final byte[] pubKeyBytes = keyStore.getPubkey(privateKeyAlias);
1353
1354        final PublicKey pubKey;
1355        try {
1356            final KeyFactory keyFact = KeyFactory.getInstance("RSA");
1357            pubKey = keyFact.generatePublic(new X509EncodedKeySpec(pubKeyBytes));
1358        } catch (NoSuchAlgorithmException e) {
1359            throw new IllegalStateException("Can't instantiate RSA key generator", e);
1360        } catch (InvalidKeySpecException e) {
1361            throw new IllegalStateException("keystore returned invalid key encoding", e);
1362        }
1363
1364        final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
1365        certGen.setPublicKey(pubKey);
1366        certGen.setSerialNumber(serialNumber);
1367        certGen.setSubjectDN(subjectDN);
1368        certGen.setIssuerDN(subjectDN);
1369        certGen.setNotBefore(notBefore);
1370        certGen.setNotAfter(notAfter);
1371        certGen.setSignatureAlgorithm("sha1WithRSA");
1372
1373        final X509Certificate cert = certGen.generate(privKey);
1374
1375        return cert;
1376    }
1377
1378    public void testKeyStore_SetKeyEntry_ReplacedChain_Success() throws Exception {
1379        mKeyStore.load(null, null);
1380
1381        // Create key #1
1382        {
1383            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
1384            assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1385
1386            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
1387
1388            assertTrue(key instanceof PrivateKey);
1389
1390            PrivateKey expectedKey = (PrivateKey) key;
1391
1392            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
1393                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
1394
1395            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
1396                    expectedCert.getEncoded()));
1397
1398            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1399
1400            assertTrue(entry instanceof PrivateKeyEntry);
1401
1402            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1403
1404            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
1405        }
1406
1407        // Replace key #1 with new chain
1408        {
1409            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
1410
1411            assertTrue(key instanceof PrivateKey);
1412
1413            PrivateKey expectedKey = (PrivateKey) key;
1414
1415            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
1416                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
1417
1418            mKeyStore.setKeyEntry(TEST_ALIAS_1, expectedKey, null,
1419                    new Certificate[] { expectedCert });
1420
1421            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1422
1423            assertTrue(entry instanceof PrivateKeyEntry);
1424
1425            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1426
1427            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
1428        }
1429    }
1430
1431    public void testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Failure()
1432            throws Exception {
1433        mKeyStore.load(null, null);
1434
1435        // Create key #1
1436        {
1437            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
1438            assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1439
1440            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
1441                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
1442
1443            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
1444                    cert.getEncoded()));
1445        }
1446
1447        // Create key #2
1448        {
1449            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_2;
1450            assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1451
1452            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
1453                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
1454
1455            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_2,
1456                    cert.getEncoded()));
1457        }
1458
1459        // Replace key #1 with key #2
1460        {
1461            Key key1 = mKeyStore.getKey(TEST_ALIAS_2, null);
1462
1463            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
1464                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
1465
1466            try {
1467                mKeyStore.setKeyEntry(TEST_ALIAS_1, key1, null, new Certificate[] { cert });
1468                fail("Should not allow setting of KeyEntry with wrong PrivaetKey");
1469            } catch (KeyStoreException success) {
1470            }
1471        }
1472    }
1473
1474    public void testKeyStore_Size_Success() throws Exception {
1475        mKeyStore.load(null, null);
1476
1477        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
1478
1479        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
1480        assertAliases(new String[] { TEST_ALIAS_1 });
1481
1482        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
1483
1484        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
1485        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
1486
1487        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));
1488
1489        assertEquals("The keystore size should match expected", 3, mKeyStore.size());
1490        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
1491
1492        assertTrue(mAndroidKeyStore.delete(Credentials.CA_CERTIFICATE + TEST_ALIAS_1));
1493
1494        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
1495        assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
1496
1497        assertTrue(mAndroidKeyStore.delKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));
1498
1499        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
1500        assertAliases(new String[] { TEST_ALIAS_2 });
1501    }
1502
1503    public void testKeyStore_Store_LoadStoreParam_Failure() throws Exception {
1504        mKeyStore.load(null, null);
1505
1506        try {
1507            mKeyStore.store(null);
1508            fail("Should throw UnsupportedOperationException when trying to store");
1509        } catch (UnsupportedOperationException success) {
1510        }
1511    }
1512
1513    public void testKeyStore_Load_InputStreamSupplied_Failure() throws Exception {
1514        byte[] buf = "FAKE KEYSTORE".getBytes();
1515        ByteArrayInputStream is = new ByteArrayInputStream(buf);
1516
1517        try {
1518            mKeyStore.load(is, null);
1519            fail("Should throw IllegalArgumentException when InputStream is supplied");
1520        } catch (IllegalArgumentException success) {
1521        }
1522    }
1523
1524    public void testKeyStore_Load_PasswordSupplied_Failure() throws Exception {
1525        try {
1526            mKeyStore.load(null, "password".toCharArray());
1527            fail("Should throw IllegalArgumentException when password is supplied");
1528        } catch (IllegalArgumentException success) {
1529        }
1530    }
1531
1532    public void testKeyStore_Store_OutputStream_Failure() throws Exception {
1533        mKeyStore.load(null, null);
1534
1535        OutputStream sink = new ByteArrayOutputStream();
1536        try {
1537            mKeyStore.store(sink, null);
1538            fail("Should throw UnsupportedOperationException when trying to store");
1539        } catch (UnsupportedOperationException success) {
1540        }
1541
1542        try {
1543            mKeyStore.store(sink, "blah".toCharArray());
1544            fail("Should throw UnsupportedOperationException when trying to store");
1545        } catch (UnsupportedOperationException success) {
1546        }
1547    }
1548}
1549