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