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