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