AndroidKeyStoreTest.java revision 12e752225aa96888358294be0d725d499a1c9f03
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 com.android.org.conscrypt.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        assertFalse(mAndroidKeyStore.isUnlocked());
471
472        mKeyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
473    }
474
475    private void setupPassword() {
476        assertTrue(mAndroidKeyStore.password("1111"));
477        assertTrue(mAndroidKeyStore.isUnlocked());
478
479        assertEquals(0, mAndroidKeyStore.saw("").length);
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_Encrypted_Success() throws Exception {
501        setupPassword();
502
503        mKeyStore.load(null, null);
504
505        assertAliases(new String[] {});
506
507        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1));
508
509        assertAliases(new String[] { TEST_ALIAS_1 });
510
511        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
512
513        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
514    }
515
516    public void testKeyStore_Aliases_NotInitialized_Encrypted_Failure() throws Exception {
517        setupPassword();
518
519        try {
520            mKeyStore.aliases();
521            fail("KeyStore should throw exception when not initialized");
522        } catch (KeyStoreException success) {
523        }
524    }
525
526    public void testKeyStore_ContainsAliases_PrivateAndCA_Encrypted_Success() throws Exception {
527        setupPassword();
528
529        mKeyStore.load(null, null);
530
531        assertAliases(new String[] {});
532
533        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1));
534
535        assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));
536
537        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
538
539        assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
540
541        assertFalse("Should not contain unadded certificate alias",
542                mKeyStore.containsAlias(TEST_ALIAS_3));
543    }
544
545    public void testKeyStore_ContainsAliases_CAOnly_Encrypted_Success() throws Exception {
546        setupPassword();
547
548        mKeyStore.load(null, null);
549
550        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
551
552        assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
553    }
554
555    public void testKeyStore_ContainsAliases_NonExistent_Encrypted_Failure() throws Exception {
556        setupPassword();
557
558        mKeyStore.load(null, null);
559
560        assertFalse("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_1));
561    }
562
563    public void testKeyStore_DeleteEntry_Encrypted_Success() throws Exception {
564        setupPassword();
565
566        mKeyStore.load(null, null);
567
568        // TEST_ALIAS_1
569        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
570                FAKE_KEY_1));
571        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
572        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
573
574        // TEST_ALIAS_2
575        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
576
577        // TEST_ALIAS_3
578        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_3, FAKE_CA_1));
579
580        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
581
582        mKeyStore.deleteEntry(TEST_ALIAS_1);
583
584        assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
585
586        mKeyStore.deleteEntry(TEST_ALIAS_3);
587
588        assertAliases(new String[] { TEST_ALIAS_2 });
589
590        mKeyStore.deleteEntry(TEST_ALIAS_2);
591
592        assertAliases(new String[] { });
593    }
594
595    public void testKeyStore_DeleteEntry_EmptyStore_Encrypted_Success() throws Exception {
596        setupPassword();
597
598        mKeyStore.load(null, null);
599
600        // Should not throw when a non-existent entry is requested for delete.
601        mKeyStore.deleteEntry(TEST_ALIAS_1);
602    }
603
604    public void testKeyStore_DeleteEntry_NonExistent_Encrypted_Success() throws Exception {
605        setupPassword();
606
607        mKeyStore.load(null, null);
608
609        // TEST_ALIAS_1
610        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
611                FAKE_KEY_1));
612        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
613        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
614
615        // Should not throw when a non-existent entry is requested for delete.
616        mKeyStore.deleteEntry(TEST_ALIAS_2);
617    }
618
619    public void testKeyStore_GetCertificate_Single_Encrypted_Success() throws Exception {
620        setupPassword();
621
622        mKeyStore.load(null, null);
623
624        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
625
626        assertAliases(new String[] { TEST_ALIAS_1 });
627
628        assertNull("Certificate should not exist in keystore",
629                mKeyStore.getCertificate(TEST_ALIAS_2));
630
631        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
632
633        assertNotNull("Retrieved certificate should not be null", retrieved);
634
635        CertificateFactory f = CertificateFactory.getInstance("X.509");
636        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
637
638        assertEquals("Actual and retrieved certificates should be the same", actual, retrieved);
639    }
640
641    public void testKeyStore_GetCertificate_NonExist_Encrypted_Failure() throws Exception {
642        setupPassword();
643
644        mKeyStore.load(null, null);
645
646        assertNull("Certificate should not exist in keystore",
647                mKeyStore.getCertificate(TEST_ALIAS_1));
648    }
649
650    public void testKeyStore_GetCertificateAlias_CAEntry_Encrypted_Success() throws Exception {
651        setupPassword();
652
653        mKeyStore.load(null, null);
654
655        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
656
657        CertificateFactory f = CertificateFactory.getInstance("X.509");
658        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
659
660        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
661                mKeyStore.getCertificateAlias(actual));
662    }
663
664    public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Encrypted_Success()
665            throws Exception {
666        setupPassword();
667
668        mKeyStore.load(null, null);
669
670        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
671                FAKE_KEY_1));
672        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
673        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
674
675        CertificateFactory f = CertificateFactory.getInstance("X.509");
676        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
677
678        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
679                mKeyStore.getCertificateAlias(actual));
680    }
681
682    public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Encrypted_Success()
683            throws Exception {
684        setupPassword();
685
686        mKeyStore.load(null, null);
687
688        // Insert TrustedCertificateEntry with CA name
689        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
690
691        // Insert PrivateKeyEntry that uses the same CA
692        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
693                FAKE_KEY_1));
694        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
695        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
696
697        CertificateFactory f = CertificateFactory.getInstance("X.509");
698        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
699
700        assertEquals("Stored certificate alias should be found", TEST_ALIAS_2,
701                mKeyStore.getCertificateAlias(actual));
702    }
703
704    public void testKeyStore_GetCertificateAlias_NonExist_Empty_Encrypted_Failure()
705            throws Exception {
706        setupPassword();
707
708        mKeyStore.load(null, null);
709
710        CertificateFactory f = CertificateFactory.getInstance("X.509");
711        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
712
713        assertNull("Stored certificate alias should not be found",
714                mKeyStore.getCertificateAlias(actual));
715    }
716
717    public void testKeyStore_GetCertificateAlias_NonExist_Encrypted_Failure() throws Exception {
718        setupPassword();
719
720        mKeyStore.load(null, null);
721
722        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
723
724        CertificateFactory f = CertificateFactory.getInstance("X.509");
725        Certificate userCert = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
726
727        assertNull("Stored certificate alias should be found",
728                mKeyStore.getCertificateAlias(userCert));
729    }
730
731    public void testKeyStore_GetCertificateChain_SingleLength_Encrypted_Success() throws Exception {
732        setupPassword();
733
734        mKeyStore.load(null, null);
735
736        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
737                FAKE_KEY_1));
738        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
739        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
740
741        CertificateFactory cf = CertificateFactory.getInstance("X.509");
742        Certificate[] expected = new Certificate[2];
743        expected[0] = cf.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
744        expected[1] = cf.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
745
746        Certificate[] actual = mKeyStore.getCertificateChain(TEST_ALIAS_1);
747
748        assertNotNull("Returned certificate chain should not be null", actual);
749        assertEquals("Returned certificate chain should be correct size", expected.length,
750                actual.length);
751        assertEquals("First certificate should be user certificate", expected[0], actual[0]);
752        assertEquals("Second certificate should be CA certificate", expected[1], actual[1]);
753
754        // Negative test when keystore is populated.
755        assertNull("Stored certificate alias should not be found",
756                mKeyStore.getCertificateChain(TEST_ALIAS_2));
757    }
758
759    public void testKeyStore_GetCertificateChain_NonExist_Encrypted_Failure() throws Exception {
760        setupPassword();
761
762        mKeyStore.load(null, null);
763
764        assertNull("Stored certificate alias should not be found",
765                mKeyStore.getCertificateChain(TEST_ALIAS_1));
766    }
767
768    public void testKeyStore_GetCreationDate_PrivateKeyEntry_Encrypted_Success() throws Exception {
769        setupPassword();
770
771        mKeyStore.load(null, null);
772
773        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
774                FAKE_KEY_1));
775        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
776        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
777
778        Date now = new Date();
779        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
780
781        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
782        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
783
784        assertTrue("Time should be close to current time", actual.before(expectedBefore));
785        assertTrue("Time should be close to current time", actual.after(expectedAfter));
786    }
787
788    public void testKeyStore_GetCreationDate_PrivateKeyEntry_Unencrypted_Success() throws Exception {
789        mKeyStore.load(null, null);
790
791        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
792                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
793        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
794                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
795        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
796                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
797
798        Date now = new Date();
799        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
800
801        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
802        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
803
804        assertTrue("Time should be close to current time", actual.before(expectedBefore));
805        assertTrue("Time should be close to current time", actual.after(expectedAfter));
806    }
807
808    public void testKeyStore_GetCreationDate_CAEntry_Encrypted_Success() throws Exception {
809        setupPassword();
810
811        mKeyStore.load(null, null);
812
813        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
814
815        Date now = new Date();
816        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
817        assertNotNull("Certificate should be found", actual);
818
819        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
820        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
821
822        assertTrue("Time should be close to current time", actual.before(expectedBefore));
823        assertTrue("Time should be close to current time", actual.after(expectedAfter));
824    }
825
826    public void testKeyStore_GetEntry_NullParams_Encrypted_Success() throws Exception {
827        setupPassword();
828
829        mKeyStore.load(null, null);
830
831        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
832                FAKE_KEY_1));
833        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
834        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
835
836        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
837        assertNotNull("Entry should exist", entry);
838
839        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
840
841        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
842
843        assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
844    }
845
846    public void testKeyStore_GetEntry_NullParams_Unencrypted_Success() throws Exception {
847        mKeyStore.load(null, null);
848
849        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
850                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
851        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
852                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
853        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
854                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
855
856        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
857        assertNotNull("Entry should exist", entry);
858
859        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
860
861        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
862
863        assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
864    }
865
866    @SuppressWarnings("unchecked")
867    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, byte[] key, byte[] cert,
868            byte[] ca) throws Exception {
869        KeyFactory keyFact = KeyFactory.getInstance("RSA");
870        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(key));
871
872        CertificateFactory certFact = CertificateFactory.getInstance("X.509");
873        Certificate expectedCert = certFact.generateCertificate(new ByteArrayInputStream(cert));
874
875        final Collection<Certificate> expectedChain;
876        if (ca != null) {
877            expectedChain = (Collection<Certificate>) certFact
878                    .generateCertificates(new ByteArrayInputStream(ca));
879        } else {
880            expectedChain = null;
881        }
882
883        assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, expectedChain);
884    }
885
886    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey,
887            Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception {
888        assertEquals("Returned PrivateKey should be what we inserted",
889                ((RSAPrivateKey) expectedKey).getModulus(),
890                ((RSAPrivateKey) keyEntry.getPrivateKey()).getModulus());
891
892        assertEquals("Returned Certificate should be what we inserted", expectedCert,
893                keyEntry.getCertificate());
894
895        Certificate[] actualChain = keyEntry.getCertificateChain();
896
897        assertEquals("First certificate in chain should be user cert", expectedCert, actualChain[0]);
898
899        if (expectedChain == null) {
900            assertEquals("Certificate chain should not include CAs", 1, actualChain.length);
901        } else {
902            int i = 1;
903            final Iterator<Certificate> it = expectedChain.iterator();
904            while (it.hasNext()) {
905                assertEquals("CA chain certificate should equal what we put in", it.next(),
906                        actualChain[i++]);
907            }
908        }
909    }
910
911    public void testKeyStore_GetEntry_Nonexistent_NullParams_Encrypted_Failure() throws Exception {
912        setupPassword();
913
914        mKeyStore.load(null, null);
915
916        assertNull("A non-existent entry should return null",
917                mKeyStore.getEntry(TEST_ALIAS_1, null));
918    }
919
920    public void testKeyStore_GetEntry_Nonexistent_NullParams_Unencrypted_Failure() throws Exception {
921        mKeyStore.load(null, null);
922
923        assertNull("A non-existent entry should return null",
924                mKeyStore.getEntry(TEST_ALIAS_1, null));
925    }
926
927    public void testKeyStore_GetKey_NoPassword_Encrypted_Success() throws Exception {
928        setupPassword();
929
930        mKeyStore.load(null, null);
931
932        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
933                FAKE_KEY_1));
934        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
935        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
936
937        Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
938        assertNotNull("Key should exist", key);
939
940        assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey);
941
942        RSAPrivateKey actualKey = (RSAPrivateKey) key;
943
944        KeyFactory keyFact = KeyFactory.getInstance("RSA");
945        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
946
947        assertEquals("Inserted key should be same as retrieved key",
948                ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus());
949    }
950
951    public void testKeyStore_GetKey_NoPassword_Unencrypted_Success() throws Exception {
952        mKeyStore.load(null, null);
953
954        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
955                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
956        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
957                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
958        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
959                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
960
961        Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
962        assertNotNull("Key should exist", key);
963
964        assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey);
965
966        RSAPrivateKey actualKey = (RSAPrivateKey) key;
967
968        KeyFactory keyFact = KeyFactory.getInstance("RSA");
969        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
970
971        assertEquals("Inserted key should be same as retrieved key",
972                ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus());
973    }
974
975    public void testKeyStore_GetKey_Certificate_Encrypted_Failure() throws Exception {
976        setupPassword();
977
978        mKeyStore.load(null, null);
979
980        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
981
982        assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
983    }
984
985    public void testKeyStore_GetKey_NonExistent_Encrypted_Failure() throws Exception {
986        setupPassword();
987
988        mKeyStore.load(null, null);
989
990        assertNull("A non-existent entry should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
991    }
992
993    public void testKeyStore_GetProvider_Encrypted_Success() throws Exception {
994        assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
995        setupPassword();
996        assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
997    }
998
999    public void testKeyStore_GetType_Encrypted_Success() throws Exception {
1000        assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
1001        setupPassword();
1002        assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
1003    }
1004
1005    public void testKeyStore_IsCertificateEntry_CA_Encrypted_Success() throws Exception {
1006        setupPassword();
1007        mKeyStore.load(null, null);
1008
1009        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
1010
1011        assertTrue("Should return true for CA certificate",
1012                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
1013    }
1014
1015    public void testKeyStore_IsCertificateEntry_PrivateKey_Encrypted_Failure() throws Exception {
1016        setupPassword();
1017        mKeyStore.load(null, null);
1018
1019        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
1020                FAKE_KEY_1));
1021        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
1022        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
1023
1024        assertFalse("Should return false for PrivateKeyEntry",
1025                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
1026    }
1027
1028    public void testKeyStore_IsCertificateEntry_NonExist_Encrypted_Failure() throws Exception {
1029        setupPassword();
1030        mKeyStore.load(null, null);
1031
1032        assertFalse("Should return false for non-existent entry",
1033                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
1034    }
1035
1036    public void testKeyStore_IsCertificateEntry_NonExist_Unencrypted_Failure() throws Exception {
1037        mKeyStore.load(null, null);
1038
1039        assertFalse("Should return false for non-existent entry",
1040                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
1041    }
1042
1043    public void testKeyStore_IsKeyEntry_PrivateKey_Encrypted_Success() throws Exception {
1044        setupPassword();
1045        mKeyStore.load(null, null);
1046
1047        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
1048                FAKE_KEY_1));
1049        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
1050        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
1051
1052        assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1));
1053    }
1054
1055    public void testKeyStore_IsKeyEntry_CA_Encrypted_Failure() throws Exception {
1056        setupPassword();
1057        mKeyStore.load(null, null);
1058
1059        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
1060
1061        assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1));
1062    }
1063
1064    public void testKeyStore_IsKeyEntry_NonExist_Encrypted_Failure() throws Exception {
1065        setupPassword();
1066        mKeyStore.load(null, null);
1067
1068        assertFalse("Should return false for non-existent entry",
1069                mKeyStore.isKeyEntry(TEST_ALIAS_1));
1070    }
1071
1072    public void testKeyStore_SetCertificate_CA_Encrypted_Success() throws Exception {
1073        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1074        final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1075
1076        setupPassword();
1077        mKeyStore.load(null, null);
1078
1079        mKeyStore.setCertificateEntry(TEST_ALIAS_1, actual);
1080        assertAliases(new String[] { TEST_ALIAS_1 });
1081
1082        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
1083
1084        assertEquals("Retrieved certificate should be the same as the one inserted", actual,
1085                retrieved);
1086    }
1087
1088    public void testKeyStore_SetCertificate_CAExists_Overwrite_Encrypted_Success() throws Exception {
1089        setupPassword();
1090        mKeyStore.load(null, null);
1091
1092        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
1093
1094        assertAliases(new String[] { TEST_ALIAS_1 });
1095
1096        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1097        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1098
1099        // TODO have separate FAKE_CA for second test
1100        mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
1101
1102        assertAliases(new String[] { TEST_ALIAS_1 });
1103    }
1104
1105    public void testKeyStore_SetCertificate_PrivateKeyExists_Encrypted_Failure() throws Exception {
1106        setupPassword();
1107        mKeyStore.load(null, null);
1108
1109        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
1110                FAKE_KEY_1));
1111        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
1112        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
1113
1114        assertAliases(new String[] { TEST_ALIAS_1 });
1115
1116        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1117        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1118
1119        try {
1120            mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
1121            fail("Should throw when trying to overwrite a PrivateKey entry with a Certificate");
1122        } catch (KeyStoreException success) {
1123        }
1124    }
1125
1126    public void testKeyStore_SetEntry_PrivateKeyEntry_Encrypted_Success() throws Exception {
1127        setupPassword();
1128        mKeyStore.load(null, null);
1129
1130        KeyFactory keyFact = KeyFactory.getInstance("RSA");
1131        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1132
1133        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1134
1135        final Certificate[] expectedChain = new Certificate[2];
1136        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1137        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1138
1139        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1140
1141        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1142
1143        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1144        assertNotNull("Retrieved entry should exist", actualEntry);
1145
1146        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1147                actualEntry instanceof PrivateKeyEntry);
1148
1149        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1150
1151        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1152    }
1153
1154    public void testKeyStore_SetEntry_PrivateKeyEntry_Unencrypted_Success() throws Exception {
1155        mKeyStore.load(null, null);
1156
1157        KeyFactory keyFact = KeyFactory.getInstance("RSA");
1158        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1159
1160        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1161
1162        final Certificate[] expectedChain = new Certificate[2];
1163        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1164        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1165
1166        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1167
1168        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1169
1170        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1171        assertNotNull("Retrieved entry should exist", actualEntry);
1172
1173        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1174                actualEntry instanceof PrivateKeyEntry);
1175
1176        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1177
1178        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1179    }
1180
1181    public void testKeyStore_SetEntry_PrivateKeyEntry_Params_Unencrypted_Failure() throws Exception {
1182        mKeyStore.load(null, null);
1183
1184        KeyFactory keyFact = KeyFactory.getInstance("RSA");
1185        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1186
1187        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1188
1189        final Certificate[] expectedChain = new Certificate[2];
1190        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1191        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1192
1193        PrivateKeyEntry entry = new PrivateKeyEntry(expectedKey, expectedChain);
1194
1195        try {
1196            mKeyStore.setEntry(TEST_ALIAS_1, entry,
1197                    new AndroidKeyStoreParameter.Builder(getContext())
1198                    .setEncryptionRequired()
1199                    .build());
1200            fail("Shouldn't be able to insert encrypted entry when KeyStore uninitialized");
1201        } catch (KeyStoreException expected) {
1202        }
1203
1204        assertNull(mKeyStore.getEntry(TEST_ALIAS_1, null));
1205    }
1206
1207    public void
1208            testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Encrypted_Success()
1209            throws Exception {
1210        setupPassword();
1211        mKeyStore.load(null, null);
1212
1213        final KeyFactory keyFact = KeyFactory.getInstance("RSA");
1214        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1215
1216        // Start with PrivateKeyEntry
1217        {
1218            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1219
1220            final Certificate[] expectedChain = new Certificate[2];
1221            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1222            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1223
1224            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1225
1226            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1227
1228            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1229            assertNotNull("Retrieved entry should exist", actualEntry);
1230
1231            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1232                    actualEntry instanceof PrivateKeyEntry);
1233
1234            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1235
1236            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1237        }
1238
1239        // TODO make entirely new test vector for the overwrite
1240        // Replace with PrivateKeyEntry
1241        {
1242            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1243
1244            final Certificate[] expectedChain = new Certificate[2];
1245            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1246            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1247
1248            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1249
1250            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1251
1252            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1253            assertNotNull("Retrieved entry should exist", actualEntry);
1254
1255            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1256                    actualEntry instanceof PrivateKeyEntry);
1257
1258            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1259
1260            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1261        }
1262    }
1263
1264    public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Encrypted_Success()
1265            throws Exception {
1266        setupPassword();
1267        mKeyStore.load(null, null);
1268
1269        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1270
1271        // Start with TrustedCertificateEntry
1272        {
1273            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1274
1275            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1276            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1277
1278            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1279            assertNotNull("Retrieved entry should exist", actualEntry);
1280            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1281                    actualEntry instanceof TrustedCertificateEntry);
1282            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1283            assertEquals("Stored and retrieved certificates should be the same",
1284                    expectedCertEntry.getTrustedCertificate(),
1285                    actualCertEntry.getTrustedCertificate());
1286        }
1287
1288        // Replace with PrivateKeyEntry
1289        {
1290            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1291            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1292            final Certificate[] expectedChain = new Certificate[2];
1293            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1294            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1295
1296            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1297
1298            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1299
1300            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1301            assertNotNull("Retrieved entry should exist", actualEntry);
1302            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1303                    actualEntry instanceof PrivateKeyEntry);
1304
1305            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1306            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1307        }
1308    }
1309
1310    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Encrypted_Success()
1311            throws Exception {
1312        setupPassword();
1313        mKeyStore.load(null, null);
1314
1315        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1316
1317        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1318
1319        // Start with PrivateKeyEntry
1320        {
1321            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1322            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1323            final Certificate[] expectedChain = new Certificate[2];
1324            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1325            expectedChain[1] = caCert;
1326
1327            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1328
1329            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1330
1331            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1332            assertNotNull("Retrieved entry should exist", actualEntry);
1333            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1334                    actualEntry instanceof PrivateKeyEntry);
1335
1336            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1337            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1338        }
1339
1340        // Replace with TrustedCertificateEntry
1341        {
1342            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1343            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1344
1345            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1346            assertNotNull("Retrieved entry should exist", actualEntry);
1347            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1348                    actualEntry instanceof TrustedCertificateEntry);
1349            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1350            assertEquals("Stored and retrieved certificates should be the same",
1351                    expectedCertEntry.getTrustedCertificate(),
1352                    actualCertEntry.getTrustedCertificate());
1353        }
1354    }
1355
1356    public
1357            void
1358            testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Encrypted_Success()
1359            throws Exception {
1360        setupPassword();
1361        mKeyStore.load(null, null);
1362
1363        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1364
1365        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1366
1367        // Start with PrivateKeyEntry
1368        {
1369            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1370            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1371            final Certificate[] expectedChain = new Certificate[2];
1372            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1373            expectedChain[1] = caCert;
1374
1375            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1376
1377            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1378
1379            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1380            assertNotNull("Retrieved entry should exist", actualEntry);
1381            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1382                    actualEntry instanceof PrivateKeyEntry);
1383
1384            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1385            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1386        }
1387
1388        // Replace with PrivateKeyEntry that has no chain
1389        {
1390            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1391            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1392            final Certificate[] expectedChain = new Certificate[1];
1393            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1394
1395            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1396
1397            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1398
1399            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1400            assertNotNull("Retrieved entry should exist", actualEntry);
1401            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1402                    actualEntry instanceof PrivateKeyEntry);
1403
1404            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1405            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, null);
1406        }
1407    }
1408
1409    public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Encrypted_Success()
1410            throws Exception {
1411        setupPassword();
1412        mKeyStore.load(null, null);
1413
1414        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1415
1416        // Insert TrustedCertificateEntry
1417        {
1418            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1419
1420            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1421            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1422
1423            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1424            assertNotNull("Retrieved entry should exist", actualEntry);
1425            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1426                    actualEntry instanceof TrustedCertificateEntry);
1427            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1428            assertEquals("Stored and retrieved certificates should be the same",
1429                    expectedCertEntry.getTrustedCertificate(),
1430                    actualCertEntry.getTrustedCertificate());
1431        }
1432
1433        // Replace with TrustedCertificateEntry of USER
1434        {
1435            final Certificate userCert = f
1436                    .generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1437
1438            TrustedCertificateEntry expectedUserEntry = new TrustedCertificateEntry(userCert);
1439            mKeyStore.setEntry(TEST_ALIAS_1, expectedUserEntry, null);
1440
1441            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1442            assertNotNull("Retrieved entry should exist", actualEntry);
1443            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1444                    actualEntry instanceof TrustedCertificateEntry);
1445            TrustedCertificateEntry actualUserEntry = (TrustedCertificateEntry) actualEntry;
1446            assertEquals("Stored and retrieved certificates should be the same",
1447                    expectedUserEntry.getTrustedCertificate(),
1448                    actualUserEntry.getTrustedCertificate());
1449        }
1450    }
1451
1452    public void testKeyStore_SetKeyEntry_ProtectedKey_Encrypted_Failure() throws Exception {
1453        setupPassword();
1454        mKeyStore.load(null, null);
1455
1456        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1457
1458        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1459
1460        KeyFactory keyFact = KeyFactory.getInstance("RSA");
1461        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1462        final Certificate[] chain = new Certificate[2];
1463        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1464        chain[1] = caCert;
1465
1466        try {
1467            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, "foo".toCharArray(), chain);
1468            fail("Should fail when a password is specified");
1469        } catch (KeyStoreException success) {
1470        }
1471    }
1472
1473    public void testKeyStore_SetKeyEntry_Encrypted_Success() throws Exception {
1474        setupPassword();
1475        mKeyStore.load(null, null);
1476
1477        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1478
1479        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1480
1481        KeyFactory keyFact = KeyFactory.getInstance("RSA");
1482        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1483        final Certificate[] chain = new Certificate[2];
1484        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1485        chain[1] = caCert;
1486
1487        mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1488
1489        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1490        assertNotNull("Retrieved entry should exist", actualEntry);
1491
1492        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1493                actualEntry instanceof PrivateKeyEntry);
1494
1495        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1496
1497        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1498    }
1499
1500    public void testKeyStore_SetKeyEntry_Replaced_Encrypted_Success() throws Exception {
1501        setupPassword();
1502        mKeyStore.load(null, null);
1503
1504        final CertificateFactory f = CertificateFactory.getInstance("X.509");
1505
1506        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
1507
1508        // Insert initial key
1509        {
1510            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1511            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1512            final Certificate[] chain = new Certificate[2];
1513            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1514            chain[1] = caCert;
1515
1516            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1517
1518            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1519            assertNotNull("Retrieved entry should exist", actualEntry);
1520
1521            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1522                    actualEntry instanceof PrivateKeyEntry);
1523
1524            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1525
1526            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1527        }
1528
1529        // TODO make a separate key
1530        // Replace key
1531        {
1532            KeyFactory keyFact = KeyFactory.getInstance("RSA");
1533            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
1534            final Certificate[] chain = new Certificate[2];
1535            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
1536            chain[1] = caCert;
1537
1538            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1539
1540            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1541            assertNotNull("Retrieved entry should exist", actualEntry);
1542
1543            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1544                    actualEntry instanceof PrivateKeyEntry);
1545
1546            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1547
1548            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
1549        }
1550    }
1551
1552    @SuppressWarnings("deprecation")
1553    private static X509Certificate generateCertificate(android.security.KeyStore keyStore,
1554            String alias, BigInteger serialNumber, X500Principal subjectDN, Date notBefore,
1555            Date notAfter) throws Exception {
1556        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
1557
1558        final PrivateKey privKey;
1559        final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore");
1560        try {
1561            privKey = engine.getPrivateKeyById(privateKeyAlias);
1562        } catch (InvalidKeyException e) {
1563            throw new RuntimeException("Can't get key", e);
1564        }
1565
1566        final byte[] pubKeyBytes = keyStore.getPubkey(privateKeyAlias);
1567
1568        final PublicKey pubKey;
1569        try {
1570            final KeyFactory keyFact = KeyFactory.getInstance("RSA");
1571            pubKey = keyFact.generatePublic(new X509EncodedKeySpec(pubKeyBytes));
1572        } catch (NoSuchAlgorithmException e) {
1573            throw new IllegalStateException("Can't instantiate RSA key generator", e);
1574        } catch (InvalidKeySpecException e) {
1575            throw new IllegalStateException("keystore returned invalid key encoding", e);
1576        }
1577
1578        final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
1579        certGen.setPublicKey(pubKey);
1580        certGen.setSerialNumber(serialNumber);
1581        certGen.setSubjectDN(subjectDN);
1582        certGen.setIssuerDN(subjectDN);
1583        certGen.setNotBefore(notBefore);
1584        certGen.setNotAfter(notAfter);
1585        certGen.setSignatureAlgorithm("sha1WithRSA");
1586
1587        final X509Certificate cert = certGen.generate(privKey);
1588
1589        return cert;
1590    }
1591
1592    public void testKeyStore_SetKeyEntry_ReplacedChain_Encrypted_Success() throws Exception {
1593        setupPassword();
1594        mKeyStore.load(null, null);
1595
1596        // Create key #1
1597        {
1598            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
1599            assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1600
1601            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
1602
1603            assertTrue(key instanceof PrivateKey);
1604
1605            PrivateKey expectedKey = (PrivateKey) key;
1606
1607            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
1608                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
1609
1610            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
1611                    expectedCert.getEncoded()));
1612
1613            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1614
1615            assertTrue(entry instanceof PrivateKeyEntry);
1616
1617            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1618
1619            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
1620        }
1621
1622        // Replace key #1 with new chain
1623        {
1624            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
1625
1626            assertTrue(key instanceof PrivateKey);
1627
1628            PrivateKey expectedKey = (PrivateKey) key;
1629
1630            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
1631                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
1632
1633            mKeyStore.setKeyEntry(TEST_ALIAS_1, expectedKey, null,
1634                    new Certificate[] { expectedCert });
1635
1636            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1637
1638            assertTrue(entry instanceof PrivateKeyEntry);
1639
1640            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1641
1642            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
1643        }
1644    }
1645
1646    public void testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Encrypted_Failure()
1647            throws Exception {
1648        setupPassword();
1649        mKeyStore.load(null, null);
1650
1651        // Create key #1
1652        {
1653            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
1654            assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1655
1656            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
1657                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
1658
1659            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
1660                    cert.getEncoded()));
1661        }
1662
1663        // Create key #2
1664        {
1665            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_2;
1666            assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1667
1668            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
1669                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
1670
1671            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_2,
1672                    cert.getEncoded()));
1673        }
1674
1675        // Replace key #1 with key #2
1676        {
1677            Key key1 = mKeyStore.getKey(TEST_ALIAS_2, null);
1678
1679            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
1680                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
1681
1682            try {
1683                mKeyStore.setKeyEntry(TEST_ALIAS_1, key1, null, new Certificate[] { cert });
1684                fail("Should not allow setting of KeyEntry with wrong PrivaetKey");
1685            } catch (KeyStoreException success) {
1686            }
1687        }
1688    }
1689
1690    public void testKeyStore_SetKeyEntry_ReplacedChain_UnencryptedToEncrypted_Failure()
1691            throws Exception {
1692        mKeyStore.load(null, null);
1693
1694        // Create key #1
1695        {
1696            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
1697            assertTrue(mAndroidKeyStore.generate(privateKeyAlias,
1698                    android.security.KeyStore.UID_SELF, android.security.KeyStore.FLAG_NONE));
1699
1700            X509Certificate cert =
1701                    generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1, TEST_DN_1,
1702                            NOW, NOW_PLUS_10_YEARS);
1703
1704            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
1705                    cert.getEncoded(), android.security.KeyStore.UID_SELF,
1706                    android.security.KeyStore.FLAG_NONE));
1707        }
1708
1709        // Replace with one that requires encryption
1710        {
1711            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1712
1713            try {
1714                mKeyStore.setEntry(TEST_ALIAS_1, entry, new AndroidKeyStoreParameter.Builder(
1715                        getContext()).setEncryptionRequired().build());
1716                fail("Should not allow setting of Entry without unlocked keystore");
1717            } catch (KeyStoreException success) {
1718            }
1719
1720            assertTrue(mAndroidKeyStore.password("1111"));
1721            assertTrue(mAndroidKeyStore.isUnlocked());
1722
1723            mKeyStore.setEntry(TEST_ALIAS_1, entry,
1724                    new AndroidKeyStoreParameter.Builder(getContext())
1725                            .setEncryptionRequired()
1726                            .build());
1727        }
1728    }
1729
1730    public void testKeyStore_Size_Encrypted_Success() throws Exception {
1731        setupPassword();
1732        mKeyStore.load(null, null);
1733
1734        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
1735
1736        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
1737        assertAliases(new String[] { TEST_ALIAS_1 });
1738
1739        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
1740
1741        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
1742        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
1743
1744        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));
1745
1746        assertEquals("The keystore size should match expected", 3, mKeyStore.size());
1747        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
1748
1749        assertTrue(mAndroidKeyStore.delete(Credentials.CA_CERTIFICATE + TEST_ALIAS_1));
1750
1751        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
1752        assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
1753
1754        assertTrue(mAndroidKeyStore.delKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));
1755
1756        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
1757        assertAliases(new String[] { TEST_ALIAS_2 });
1758    }
1759
1760    public void testKeyStore_Store_LoadStoreParam_Encrypted_Failure() throws Exception {
1761        setupPassword();
1762        mKeyStore.load(null, null);
1763
1764        try {
1765            mKeyStore.store(null);
1766            fail("Should throw UnsupportedOperationException when trying to store");
1767        } catch (UnsupportedOperationException success) {
1768        }
1769    }
1770
1771    public void testKeyStore_Load_InputStreamSupplied_Encrypted_Failure() throws Exception {
1772        byte[] buf = "FAKE KEYSTORE".getBytes();
1773        ByteArrayInputStream is = new ByteArrayInputStream(buf);
1774
1775        try {
1776            mKeyStore.load(is, null);
1777            fail("Should throw IllegalArgumentException when InputStream is supplied");
1778        } catch (IllegalArgumentException success) {
1779        }
1780    }
1781
1782    public void testKeyStore_Load_PasswordSupplied_Encrypted_Failure() throws Exception {
1783        try {
1784            mKeyStore.load(null, "password".toCharArray());
1785            fail("Should throw IllegalArgumentException when password is supplied");
1786        } catch (IllegalArgumentException success) {
1787        }
1788    }
1789
1790    public void testKeyStore_Store_OutputStream_Encrypted_Failure() throws Exception {
1791        setupPassword();
1792        mKeyStore.load(null, null);
1793
1794        OutputStream sink = new ByteArrayOutputStream();
1795        try {
1796            mKeyStore.store(sink, null);
1797            fail("Should throw UnsupportedOperationException when trying to store");
1798        } catch (UnsupportedOperationException success) {
1799        }
1800
1801        try {
1802            mKeyStore.store(sink, "blah".toCharArray());
1803            fail("Should throw UnsupportedOperationException when trying to store");
1804        } catch (UnsupportedOperationException success) {
1805        }
1806    }
1807
1808    private void setupKey() throws Exception {
1809        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
1810        assertTrue(mAndroidKeyStore.generate(privateKeyAlias));
1811
1812        X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1,
1813                TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
1814
1815        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
1816                cert.getEncoded()));
1817    }
1818
1819    public void testKeyStore_KeyOperations_Wrap_Encrypted_Success() throws Exception {
1820        setupPassword();
1821        mKeyStore.load(null, null);
1822
1823        setupKey();
1824
1825        // Test key usage
1826        Entry e = mKeyStore.getEntry(TEST_ALIAS_1, null);
1827        assertNotNull(e);
1828        assertTrue(e instanceof PrivateKeyEntry);
1829
1830        PrivateKeyEntry privEntry = (PrivateKeyEntry) e;
1831        PrivateKey privKey = privEntry.getPrivateKey();
1832        assertNotNull(privKey);
1833
1834        PublicKey pubKey = privEntry.getCertificate().getPublicKey();
1835
1836        Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
1837        c.init(Cipher.WRAP_MODE, pubKey);
1838
1839        byte[] expectedKey = new byte[] {
1840                0x00, 0x05, (byte) 0xAA, (byte) 0x0A5, (byte) 0xFF, 0x55, 0x0A
1841        };
1842
1843        SecretKey expectedSecret = new SecretKeySpec(expectedKey, "AES");
1844
1845        byte[] wrappedExpected = c.wrap(expectedSecret);
1846
1847        c.init(Cipher.UNWRAP_MODE, privKey);
1848        SecretKey actualSecret = (SecretKey) c.unwrap(wrappedExpected, "AES", Cipher.SECRET_KEY);
1849
1850        assertEquals(Arrays.toString(expectedSecret.getEncoded()),
1851                Arrays.toString(actualSecret.getEncoded()));
1852    }
1853}
1854