1 /*
2  * Copyright 2013 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 
17 package android.keystore.cts;
18 
19 import android.content.pm.PackageManager;
20 import android.security.KeyPairGeneratorSpec;
21 import android.security.keystore.KeyGenParameterSpec;
22 import android.security.keystore.KeyProperties;
23 import android.security.keystore.KeyProtection;
24 import android.test.AndroidTestCase;
25 import android.test.MoreAsserts;
26 import android.test.suitebuilder.annotation.LargeTest;
27 import android.util.Log;
28 
29 import org.junit.Assert;
30 
31 import java.io.ByteArrayInputStream;
32 import java.io.ByteArrayOutputStream;
33 import java.io.OutputStream;
34 import java.math.BigInteger;
35 import java.security.AlgorithmParameters;
36 import java.security.Key;
37 import java.security.KeyFactory;
38 import java.security.KeyPairGenerator;
39 import java.security.KeyStore;
40 import java.security.KeyStore.Entry;
41 import java.security.KeyStore.PrivateKeyEntry;
42 import java.security.KeyStore.TrustedCertificateEntry;
43 import java.security.KeyStoreException;
44 import java.security.PrivateKey;
45 import java.security.PublicKey;
46 import java.security.Signature;
47 import java.security.cert.Certificate;
48 import java.security.cert.CertificateFactory;
49 import java.security.interfaces.ECKey;
50 import java.security.interfaces.RSAKey;
51 import java.security.spec.PKCS8EncodedKeySpec;
52 import java.time.Duration;
53 import java.util.ArrayList;
54 import java.util.Arrays;
55 import java.util.Calendar;
56 import java.util.Collection;
57 import java.util.Date;
58 import java.util.Enumeration;
59 import java.util.HashSet;
60 import java.util.Iterator;
61 import java.util.Set;
62 import java.util.concurrent.atomic.AtomicInteger;
63 
64 import javax.crypto.BadPaddingException;
65 import javax.crypto.Cipher;
66 import javax.crypto.IllegalBlockSizeException;
67 import javax.crypto.KeyGenerator;
68 import javax.crypto.Mac;
69 import javax.crypto.SecretKey;
70 import javax.security.auth.x500.X500Principal;
71 
72 public class AndroidKeyStoreTest extends AndroidTestCase {
73     private static final String TAG = AndroidKeyStoreTest.class.getSimpleName();
74 
75     private KeyStore mKeyStore;
76 
77     private static final String TEST_ALIAS_1 = "test1";
78 
79     private static final String TEST_ALIAS_2 = "test2";
80 
81     private static final String TEST_ALIAS_3 = "test3";
82 
83     // The maximum amount of time the "large number of keys" tests will spend on importing keys
84     // into key store. This is used as a time box so that lower-power devices don't take too long
85     // to run the tests.
86     private Duration mMaxImportDuration;
87 
88     /*
89      * The keys and certificates below are generated with:
90      *
91      * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
92      * openssl req -newkey rsa:1024 -keyout userkey.pem -nodes -days 3650 -out userkey.req
93      * mkdir -p demoCA/newcerts
94      * touch demoCA/index.txt
95      * echo "01" > demoCA/serial
96      * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
97      */
98 
99     /**
100      * Generated from above and converted with:
101      *
102      * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
103      */
104     private static final byte[] FAKE_RSA_CA_1 = {
105             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xce, (byte) 0x30, (byte) 0x82,
106             (byte) 0x02, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
107             (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0x6a,
108             (byte) 0xa2, (byte) 0xf4, (byte) 0x2e, (byte) 0x55, (byte) 0x48, (byte) 0x0a,
109             (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
110             (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
111             (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31,
112             (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
113             (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53,
114             (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
115             (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43,
116             (byte) 0x41, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06,
117             (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d,
118             (byte) 0x4d, (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61,
119             (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65,
120             (byte) 0x77, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
121             (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12,
122             (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69,
123             (byte) 0x64, (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74,
124             (byte) 0x20, (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73,
125             (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32,
126             (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x34, (byte) 0x31, (byte) 0x36,
127             (byte) 0x35, (byte) 0x35, (byte) 0x34, (byte) 0x34, (byte) 0x5a, (byte) 0x17,
128             (byte) 0x0d, (byte) 0x32, (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31,
129             (byte) 0x32, (byte) 0x31, (byte) 0x36, (byte) 0x35, (byte) 0x35, (byte) 0x34,
130             (byte) 0x34, (byte) 0x5a, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b,
131             (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
132             (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31,
133             (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
134             (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41,
135             (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03,
136             (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d,
137             (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69,
138             (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77,
139             (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
140             (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41,
141             (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64,
142             (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20,
143             (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30,
144             (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
145             (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
146             (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
147             (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
148             (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa3, (byte) 0x72,
149             (byte) 0xab, (byte) 0xd0, (byte) 0xe4, (byte) 0xad, (byte) 0x2f, (byte) 0xe7,
150             (byte) 0xe2, (byte) 0x79, (byte) 0x07, (byte) 0x36, (byte) 0x3d, (byte) 0x0c,
151             (byte) 0x8d, (byte) 0x42, (byte) 0x9a, (byte) 0x0a, (byte) 0x33, (byte) 0x64,
152             (byte) 0xb3, (byte) 0xcd, (byte) 0xb2, (byte) 0xd7, (byte) 0x3a, (byte) 0x42,
153             (byte) 0x06, (byte) 0x77, (byte) 0x45, (byte) 0x29, (byte) 0xe9, (byte) 0xcb,
154             (byte) 0xb7, (byte) 0x4a, (byte) 0xd6, (byte) 0xee, (byte) 0xad, (byte) 0x01,
155             (byte) 0x91, (byte) 0x9b, (byte) 0x0c, (byte) 0x59, (byte) 0xa1, (byte) 0x03,
156             (byte) 0xfa, (byte) 0xf0, (byte) 0x5a, (byte) 0x7c, (byte) 0x4f, (byte) 0xf7,
157             (byte) 0x8d, (byte) 0x36, (byte) 0x0f, (byte) 0x1f, (byte) 0x45, (byte) 0x7d,
158             (byte) 0x1b, (byte) 0x31, (byte) 0xa1, (byte) 0x35, (byte) 0x0b, (byte) 0x00,
159             (byte) 0xed, (byte) 0x7a, (byte) 0xb6, (byte) 0xc8, (byte) 0x4e, (byte) 0xa9,
160             (byte) 0x86, (byte) 0x4c, (byte) 0x7b, (byte) 0x99, (byte) 0x57, (byte) 0x41,
161             (byte) 0x12, (byte) 0xef, (byte) 0x6b, (byte) 0xbc, (byte) 0x3d, (byte) 0x60,
162             (byte) 0xf2, (byte) 0x99, (byte) 0x1a, (byte) 0xcd, (byte) 0xed, (byte) 0x56,
163             (byte) 0xa4, (byte) 0xe5, (byte) 0x36, (byte) 0x9f, (byte) 0x24, (byte) 0x1f,
164             (byte) 0xdc, (byte) 0x89, (byte) 0x40, (byte) 0xc8, (byte) 0x99, (byte) 0x92,
165             (byte) 0xab, (byte) 0x4a, (byte) 0xb5, (byte) 0x61, (byte) 0x45, (byte) 0x62,
166             (byte) 0xff, (byte) 0xa3, (byte) 0x45, (byte) 0x65, (byte) 0xaf, (byte) 0xf6,
167             (byte) 0x27, (byte) 0x30, (byte) 0x51, (byte) 0x0e, (byte) 0x0e, (byte) 0xeb,
168             (byte) 0x79, (byte) 0x0c, (byte) 0xbe, (byte) 0xb3, (byte) 0x0a, (byte) 0x6f,
169             (byte) 0x29, (byte) 0x06, (byte) 0xdc, (byte) 0x2f, (byte) 0x6b, (byte) 0x51,
170             (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
171             (byte) 0x81, (byte) 0xb1, (byte) 0x30, (byte) 0x81, (byte) 0xae, (byte) 0x30,
172             (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e,
173             (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x33, (byte) 0x05,
174             (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60, (byte) 0xc7, (byte) 0xf9,
175             (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c, (byte) 0x8f, (byte) 0x6d,
176             (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e, (byte) 0x5d, (byte) 0x51,
177             (byte) 0x30, (byte) 0x7f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
178             (byte) 0x23, (byte) 0x04, (byte) 0x78, (byte) 0x30, (byte) 0x76, (byte) 0x80,
179             (byte) 0x14, (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f,
180             (byte) 0x60, (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73,
181             (byte) 0x5c, (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97,
182             (byte) 0x8e, (byte) 0x5d, (byte) 0x51, (byte) 0xa1, (byte) 0x53, (byte) 0xa4,
183             (byte) 0x51, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
184             (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
185             (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
186             (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
187             (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
188             (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
189             (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
190             (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
191             (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
192             (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
193             (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
194             (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
195             (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
196             (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x82, (byte) 0x09,
197             (byte) 0x00, (byte) 0xe1, (byte) 0x6a, (byte) 0xa2, (byte) 0xf4, (byte) 0x2e,
198             (byte) 0x55, (byte) 0x48, (byte) 0x0a, (byte) 0x30, (byte) 0x0c, (byte) 0x06,
199             (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05,
200             (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30,
201             (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
202             (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
203             (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
204             (byte) 0x8c, (byte) 0x30, (byte) 0x42, (byte) 0xfa, (byte) 0xeb, (byte) 0x1a,
205             (byte) 0x26, (byte) 0xeb, (byte) 0xda, (byte) 0x56, (byte) 0x32, (byte) 0xf2,
206             (byte) 0x9d, (byte) 0xa5, (byte) 0x24, (byte) 0xd8, (byte) 0x3a, (byte) 0xda,
207             (byte) 0x30, (byte) 0xa6, (byte) 0x8b, (byte) 0x46, (byte) 0xfe, (byte) 0xfe,
208             (byte) 0xdb, (byte) 0xf1, (byte) 0xe6, (byte) 0xe1, (byte) 0x7c, (byte) 0x1b,
209             (byte) 0xe7, (byte) 0x77, (byte) 0x00, (byte) 0xa1, (byte) 0x1c, (byte) 0x19,
210             (byte) 0x17, (byte) 0x73, (byte) 0xb0, (byte) 0xf0, (byte) 0x9d, (byte) 0xf3,
211             (byte) 0x4f, (byte) 0xb6, (byte) 0xbc, (byte) 0xc7, (byte) 0x47, (byte) 0x85,
212             (byte) 0x2a, (byte) 0x4a, (byte) 0xa1, (byte) 0xa5, (byte) 0x58, (byte) 0xf5,
213             (byte) 0xc5, (byte) 0x1a, (byte) 0x51, (byte) 0xb1, (byte) 0x04, (byte) 0x80,
214             (byte) 0xee, (byte) 0x3a, (byte) 0xec, (byte) 0x2f, (byte) 0xe1, (byte) 0xfd,
215             (byte) 0x58, (byte) 0xeb, (byte) 0xed, (byte) 0x82, (byte) 0x9e, (byte) 0x38,
216             (byte) 0xa3, (byte) 0x24, (byte) 0x75, (byte) 0xf7, (byte) 0x3e, (byte) 0xc2,
217             (byte) 0xc5, (byte) 0x27, (byte) 0xeb, (byte) 0x6f, (byte) 0x7b, (byte) 0x50,
218             (byte) 0xda, (byte) 0x43, (byte) 0xdc, (byte) 0x3b, (byte) 0x0b, (byte) 0x6f,
219             (byte) 0x78, (byte) 0x8f, (byte) 0xb0, (byte) 0x66, (byte) 0xe1, (byte) 0x12,
220             (byte) 0x87, (byte) 0x5f, (byte) 0x97, (byte) 0x7b, (byte) 0xca, (byte) 0x14,
221             (byte) 0x79, (byte) 0xf7, (byte) 0xe8, (byte) 0x6c, (byte) 0x72, (byte) 0xdb,
222             (byte) 0x91, (byte) 0x65, (byte) 0x17, (byte) 0x54, (byte) 0xe0, (byte) 0x74,
223             (byte) 0x1d, (byte) 0xac, (byte) 0x47, (byte) 0x04, (byte) 0x12, (byte) 0xe0,
224             (byte) 0xc3, (byte) 0x66, (byte) 0x19, (byte) 0x05, (byte) 0x2e, (byte) 0x7e,
225             (byte) 0xf1, (byte) 0x61
226     };
227 
228     /**
229      * Generated from above and converted with:
230      *
231      * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
232      */
233     private static final byte[] FAKE_RSA_KEY_1 = new byte[] {
234             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
235             (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
236             (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
237             (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
238             (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
239             (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
240             (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
241             (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
242             (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
243             (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
244             (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
245             (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
246             (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
247             (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
248             (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
249             (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
250             (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
251             (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
252             (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
253             (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
254             (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
255             (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
256             (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
257             (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
258             (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
259             (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
260             (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
261             (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
262             (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
263             (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
264             (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
265             (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
266             (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
267             (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
268             (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
269             (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
270             (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
271             (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
272             (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
273             (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
274             (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
275             (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
276             (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
277             (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
278             (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
279             (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
280             (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
281             (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
282             (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
283             (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
284             (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
285             (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
286             (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
287             (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
288             (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
289             (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
290             (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
291             (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
292             (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
293             (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
294             (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
295             (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
296             (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
297             (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
298             (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
299             (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
300             (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
301             (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
302             (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
303             (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
304             (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
305             (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
306             (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
307             (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
308             (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
309             (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
310             (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
311             (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
312             (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
313             (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
314             (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
315             (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
316             (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
317             (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
318             (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
319             (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
320             (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
321             (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
322             (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
323             (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
324             (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
325             (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
326             (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
327             (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
328             (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
329             (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
330             (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
331             (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
332             (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
333             (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
334             (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
335             (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
336             (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
337             (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
338             (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
339             (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
340     };
341 
342     /**
343      * Generated from above and converted with:
344      *
345      * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
346      */
347     private static final byte[] FAKE_RSA_USER_1 = new byte[] {
348             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x95, (byte) 0x30, (byte) 0x82,
349             (byte) 0x01, (byte) 0xfe, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
350             (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
351             (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
352             (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
353             (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
354             (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
355             (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
356             (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
357             (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
358             (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
359             (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
360             (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
361             (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
362             (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
363             (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
364             (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
365             (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
366             (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30, (byte) 0x1e,
367             (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32, (byte) 0x30, (byte) 0x38,
368             (byte) 0x31, (byte) 0x34, (byte) 0x32, (byte) 0x33, (byte) 0x32, (byte) 0x35,
369             (byte) 0x34, (byte) 0x38, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32,
370             (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x32,
371             (byte) 0x33, (byte) 0x32, (byte) 0x35, (byte) 0x34, (byte) 0x38, (byte) 0x5a,
372             (byte) 0x30, (byte) 0x55, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
373             (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13,
374             (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
375             (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08,
376             (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31, (byte) 0x1b,
377             (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
378             (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e, (byte) 0x64,
379             (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x54,
380             (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43, (byte) 0x61,
381             (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x31, (byte) 0x1c, (byte) 0x30,
382             (byte) 0x1a, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03,
383             (byte) 0x13, (byte) 0x13, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76,
384             (byte) 0x65, (byte) 0x72, (byte) 0x31, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
385             (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
386             (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x81, (byte) 0x9f,
387             (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
388             (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
389             (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8d,
390             (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81,
391             (byte) 0x81, (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6,
392             (byte) 0x5b, (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c,
393             (byte) 0x66, (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86,
394             (byte) 0x8a, (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3,
395             (byte) 0x02, (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08,
396             (byte) 0xf3, (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04,
397             (byte) 0x6d, (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f,
398             (byte) 0x67, (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c,
399             (byte) 0xcb, (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30,
400             (byte) 0xe2, (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5,
401             (byte) 0x79, (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b,
402             (byte) 0xce, (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb,
403             (byte) 0x08, (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff,
404             (byte) 0x3b, (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9,
405             (byte) 0xc4, (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29,
406             (byte) 0x0d, (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b,
407             (byte) 0x23, (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78,
408             (byte) 0x08, (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5,
409             (byte) 0xf1, (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19,
410             (byte) 0xb4, (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03,
411             (byte) 0x16, (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce,
412             (byte) 0x9e, (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03,
413             (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x7b, (byte) 0x30,
414             (byte) 0x79, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
415             (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00,
416             (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86,
417             (byte) 0x48, (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01,
418             (byte) 0x0d, (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f,
419             (byte) 0x70, (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c,
420             (byte) 0x20, (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72,
421             (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43,
422             (byte) 0x65, (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69,
423             (byte) 0x63, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d,
424             (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04,
425             (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x32, (byte) 0xa1, (byte) 0x1e,
426             (byte) 0x6b, (byte) 0x69, (byte) 0x04, (byte) 0xfe, (byte) 0xb3, (byte) 0xcd,
427             (byte) 0xf8, (byte) 0xbb, (byte) 0x14, (byte) 0xcd, (byte) 0xff, (byte) 0xd4,
428             (byte) 0x16, (byte) 0xc3, (byte) 0xab, (byte) 0x44, (byte) 0x2f, (byte) 0x30,
429             (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23,
430             (byte) 0x04, (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14,
431             (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60,
432             (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c,
433             (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e,
434             (byte) 0x5d, (byte) 0x51, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
435             (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
436             (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03,
437             (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x46, (byte) 0x42, (byte) 0xef,
438             (byte) 0x56, (byte) 0x89, (byte) 0x78, (byte) 0x90, (byte) 0x38, (byte) 0x24,
439             (byte) 0x9f, (byte) 0x8c, (byte) 0x7a, (byte) 0xce, (byte) 0x7a, (byte) 0xa5,
440             (byte) 0xb5, (byte) 0x1e, (byte) 0x74, (byte) 0x96, (byte) 0x34, (byte) 0x49,
441             (byte) 0x8b, (byte) 0xed, (byte) 0x44, (byte) 0xb3, (byte) 0xc9, (byte) 0x05,
442             (byte) 0xd7, (byte) 0x48, (byte) 0x55, (byte) 0x52, (byte) 0x59, (byte) 0x15,
443             (byte) 0x0b, (byte) 0xaa, (byte) 0x16, (byte) 0x86, (byte) 0xd2, (byte) 0x8e,
444             (byte) 0x16, (byte) 0x99, (byte) 0xe8, (byte) 0x5f, (byte) 0x11, (byte) 0x71,
445             (byte) 0x42, (byte) 0x55, (byte) 0xd1, (byte) 0xc4, (byte) 0x6f, (byte) 0x2e,
446             (byte) 0xa9, (byte) 0x64, (byte) 0x6f, (byte) 0xd8, (byte) 0xfd, (byte) 0x43,
447             (byte) 0x13, (byte) 0x24, (byte) 0xaa, (byte) 0x67, (byte) 0xe6, (byte) 0xf5,
448             (byte) 0xca, (byte) 0x80, (byte) 0x5e, (byte) 0x3a, (byte) 0x3e, (byte) 0xcc,
449             (byte) 0x4f, (byte) 0xba, (byte) 0x87, (byte) 0xe6, (byte) 0xae, (byte) 0xbf,
450             (byte) 0x8f, (byte) 0xd5, (byte) 0x28, (byte) 0x38, (byte) 0x58, (byte) 0x30,
451             (byte) 0x24, (byte) 0xf6, (byte) 0x53, (byte) 0x5b, (byte) 0x41, (byte) 0x53,
452             (byte) 0xe6, (byte) 0x45, (byte) 0xbc, (byte) 0xbe, (byte) 0xe6, (byte) 0xbb,
453             (byte) 0x5d, (byte) 0xd8, (byte) 0xa7, (byte) 0xf9, (byte) 0x64, (byte) 0x99,
454             (byte) 0x04, (byte) 0x43, (byte) 0x75, (byte) 0xd7, (byte) 0x2d, (byte) 0x32,
455             (byte) 0x0a, (byte) 0x94, (byte) 0xaf, (byte) 0x06, (byte) 0x34, (byte) 0xae,
456             (byte) 0x46, (byte) 0xbd, (byte) 0xda, (byte) 0x00, (byte) 0x0e, (byte) 0x25,
457             (byte) 0xc2, (byte) 0xf7, (byte) 0xc9, (byte) 0xc3, (byte) 0x65, (byte) 0xd2,
458             (byte) 0x08, (byte) 0x41, (byte) 0x0a, (byte) 0xf3, (byte) 0x72
459     };
460 
461     /*
462      * The keys and certificates below are generated with:
463      *
464      * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
465      * openssl ecparam -name prime256v1 -out ecparam.pem
466      * openssl req -newkey ec:ecparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
467      * mkdir -p demoCA/newcerts
468      * touch demoCA/index.txt
469      * echo "01" > demoCA/serial
470      * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
471      */
472 
473     /**
474      * Generated from above and converted with:
475      *
476      * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
477      */
478     private static final byte[] FAKE_EC_CA_1 = {
479             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x58, (byte) 0x30, (byte) 0x82,
480             (byte) 0x01, (byte) 0xc1, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
481             (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0xb2,
482             (byte) 0x8c, (byte) 0x04, (byte) 0x95, (byte) 0xeb, (byte) 0x10, (byte) 0xcb,
483             (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
484             (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
485             (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x45, (byte) 0x31,
486             (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
487             (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55,
488             (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03,
489             (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53,
490             (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74,
491             (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30,
492             (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
493             (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
494             (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
495             (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
496             (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
497             (byte) 0x74, (byte) 0x64, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d,
498             (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x37,
499             (byte) 0x31, (byte) 0x36, (byte) 0x32, (byte) 0x38, (byte) 0x32, (byte) 0x38,
500             (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33, (byte) 0x30,
501             (byte) 0x38, (byte) 0x32, (byte) 0x35, (byte) 0x31, (byte) 0x36, (byte) 0x32,
502             (byte) 0x38, (byte) 0x32, (byte) 0x38, (byte) 0x5a, (byte) 0x30, (byte) 0x45,
503             (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
504             (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
505             (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
506             (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a,
507             (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
508             (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21,
509             (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
510             (byte) 0x0a, (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74,
511             (byte) 0x65, (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20,
512             (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74,
513             (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20,
514             (byte) 0x4c, (byte) 0x74, (byte) 0x64, (byte) 0x30, (byte) 0x81, (byte) 0x9f,
515             (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
516             (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
517             (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8d,
518             (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81,
519             (byte) 0x81, (byte) 0x00, (byte) 0xb5, (byte) 0xf6, (byte) 0x08, (byte) 0x0f,
520             (byte) 0xc4, (byte) 0x4d, (byte) 0xe4, (byte) 0x0d, (byte) 0x34, (byte) 0x1d,
521             (byte) 0xe2, (byte) 0x23, (byte) 0x18, (byte) 0x63, (byte) 0x03, (byte) 0xf7,
522             (byte) 0x14, (byte) 0x0e, (byte) 0x98, (byte) 0xcd, (byte) 0x45, (byte) 0x1f,
523             (byte) 0xfe, (byte) 0xfb, (byte) 0x09, (byte) 0x3f, (byte) 0x5d, (byte) 0x36,
524             (byte) 0x3b, (byte) 0x0f, (byte) 0xf9, (byte) 0x5e, (byte) 0x86, (byte) 0x56,
525             (byte) 0x64, (byte) 0xd7, (byte) 0x3f, (byte) 0xae, (byte) 0x33, (byte) 0x09,
526             (byte) 0xd3, (byte) 0xdd, (byte) 0x06, (byte) 0x17, (byte) 0x26, (byte) 0xdc,
527             (byte) 0xa2, (byte) 0x8c, (byte) 0x3c, (byte) 0x65, (byte) 0xed, (byte) 0x03,
528             (byte) 0x82, (byte) 0x78, (byte) 0x9b, (byte) 0xee, (byte) 0xe3, (byte) 0x98,
529             (byte) 0x58, (byte) 0xe1, (byte) 0xf1, (byte) 0xa0, (byte) 0x85, (byte) 0xae,
530             (byte) 0x63, (byte) 0x84, (byte) 0x41, (byte) 0x46, (byte) 0xa7, (byte) 0x4f,
531             (byte) 0xdc, (byte) 0xbb, (byte) 0x1c, (byte) 0x6e, (byte) 0xec, (byte) 0x7b,
532             (byte) 0xd5, (byte) 0xab, (byte) 0x3d, (byte) 0x6a, (byte) 0x05, (byte) 0x58,
533             (byte) 0x0f, (byte) 0x9b, (byte) 0x6a, (byte) 0x67, (byte) 0x4b, (byte) 0xe9,
534             (byte) 0x2a, (byte) 0x6d, (byte) 0x96, (byte) 0x11, (byte) 0x53, (byte) 0x95,
535             (byte) 0x78, (byte) 0xaa, (byte) 0xd1, (byte) 0x91, (byte) 0x4a, (byte) 0xf8,
536             (byte) 0x54, (byte) 0x52, (byte) 0x6d, (byte) 0xb9, (byte) 0xca, (byte) 0x74,
537             (byte) 0x81, (byte) 0xf8, (byte) 0x99, (byte) 0x64, (byte) 0xd1, (byte) 0x4f,
538             (byte) 0x01, (byte) 0x38, (byte) 0x4f, (byte) 0x08, (byte) 0x5c, (byte) 0x31,
539             (byte) 0xcb, (byte) 0x7c, (byte) 0x5c, (byte) 0x78, (byte) 0x5d, (byte) 0x47,
540             (byte) 0xd9, (byte) 0xf0, (byte) 0x1a, (byte) 0xeb, (byte) 0x02, (byte) 0x03,
541             (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x50, (byte) 0x30,
542             (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
543             (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14,
544             (byte) 0x5f, (byte) 0x5b, (byte) 0x5e, (byte) 0xac, (byte) 0x29, (byte) 0xfa,
545             (byte) 0xa1, (byte) 0x9f, (byte) 0x9e, (byte) 0xad, (byte) 0x46, (byte) 0xe1,
546             (byte) 0xbc, (byte) 0x20, (byte) 0x72, (byte) 0xcf, (byte) 0x4a, (byte) 0xd4,
547             (byte) 0xfa, (byte) 0xe3, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
548             (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
549             (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x5f, (byte) 0x5b, (byte) 0x5e,
550             (byte) 0xac, (byte) 0x29, (byte) 0xfa, (byte) 0xa1, (byte) 0x9f, (byte) 0x9e,
551             (byte) 0xad, (byte) 0x46, (byte) 0xe1, (byte) 0xbc, (byte) 0x20, (byte) 0x72,
552             (byte) 0xcf, (byte) 0x4a, (byte) 0xd4, (byte) 0xfa, (byte) 0xe3, (byte) 0x30,
553             (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
554             (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01,
555             (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
556             (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
557             (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81,
558             (byte) 0x81, (byte) 0x00, (byte) 0xa1, (byte) 0x4a, (byte) 0xe6, (byte) 0xfc,
559             (byte) 0x7f, (byte) 0x17, (byte) 0xaa, (byte) 0x65, (byte) 0x4a, (byte) 0x34,
560             (byte) 0xde, (byte) 0x69, (byte) 0x67, (byte) 0x54, (byte) 0x4d, (byte) 0xa2,
561             (byte) 0xc2, (byte) 0x98, (byte) 0x02, (byte) 0x43, (byte) 0x6a, (byte) 0x0e,
562             (byte) 0x0b, (byte) 0x7f, (byte) 0xa4, (byte) 0x46, (byte) 0xaf, (byte) 0xa4,
563             (byte) 0x65, (byte) 0xa0, (byte) 0xdb, (byte) 0xf1, (byte) 0x5b, (byte) 0xd5,
564             (byte) 0x09, (byte) 0xbc, (byte) 0xee, (byte) 0x37, (byte) 0x51, (byte) 0x19,
565             (byte) 0x36, (byte) 0xc0, (byte) 0x90, (byte) 0xd3, (byte) 0x5f, (byte) 0xf3,
566             (byte) 0x4f, (byte) 0xb9, (byte) 0x08, (byte) 0x45, (byte) 0x0e, (byte) 0x01,
567             (byte) 0x8a, (byte) 0x95, (byte) 0xef, (byte) 0x92, (byte) 0x95, (byte) 0x33,
568             (byte) 0x78, (byte) 0xdd, (byte) 0x90, (byte) 0xbb, (byte) 0xf3, (byte) 0x06,
569             (byte) 0x75, (byte) 0xd0, (byte) 0x66, (byte) 0xe6, (byte) 0xd0, (byte) 0x18,
570             (byte) 0x6e, (byte) 0xeb, (byte) 0x1c, (byte) 0x52, (byte) 0xc3, (byte) 0x2e,
571             (byte) 0x57, (byte) 0x7d, (byte) 0xa9, (byte) 0x03, (byte) 0xdb, (byte) 0xf4,
572             (byte) 0x57, (byte) 0x5f, (byte) 0x6c, (byte) 0x7e, (byte) 0x00, (byte) 0x0d,
573             (byte) 0x8f, (byte) 0xe8, (byte) 0x91, (byte) 0xf7, (byte) 0xae, (byte) 0x24,
574             (byte) 0x35, (byte) 0x07, (byte) 0xb5, (byte) 0x48, (byte) 0x2d, (byte) 0x36,
575             (byte) 0x30, (byte) 0x5d, (byte) 0xe9, (byte) 0x49, (byte) 0x2d, (byte) 0xd1,
576             (byte) 0x5d, (byte) 0xc5, (byte) 0xf4, (byte) 0x33, (byte) 0x77, (byte) 0x3c,
577             (byte) 0x71, (byte) 0xad, (byte) 0x90, (byte) 0x65, (byte) 0xa9, (byte) 0xc1,
578             (byte) 0x0b, (byte) 0x5c, (byte) 0x62, (byte) 0x55, (byte) 0x50, (byte) 0x6f,
579             (byte) 0x9b, (byte) 0xc9, (byte) 0x0d, (byte) 0xee
580     };
581 
582     /**
583      * Generated from above and converted with:
584      *
585      * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
586      */
587     private static final byte[] FAKE_EC_KEY_1 = new byte[] {
588             (byte) 0x30, (byte) 0x81, (byte) 0x87, (byte) 0x02, (byte) 0x01, (byte) 0x00,
589             (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86,
590             (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06,
591             (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d,
592             (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x04, (byte) 0x6d, (byte) 0x30,
593             (byte) 0x6b, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x20,
594             (byte) 0x3a, (byte) 0x8a, (byte) 0x02, (byte) 0xdc, (byte) 0xde, (byte) 0x70,
595             (byte) 0x84, (byte) 0x45, (byte) 0x34, (byte) 0xaf, (byte) 0xbd, (byte) 0xd5,
596             (byte) 0x02, (byte) 0x17, (byte) 0x69, (byte) 0x90, (byte) 0x65, (byte) 0x1e,
597             (byte) 0x87, (byte) 0xf1, (byte) 0x3d, (byte) 0x17, (byte) 0xb6, (byte) 0xf4,
598             (byte) 0x31, (byte) 0x94, (byte) 0x86, (byte) 0x76, (byte) 0x55, (byte) 0xf7,
599             (byte) 0xcc, (byte) 0xba, (byte) 0xa1, (byte) 0x44, (byte) 0x03, (byte) 0x42,
600             (byte) 0x00, (byte) 0x04, (byte) 0xd9, (byte) 0xcf, (byte) 0xe7, (byte) 0x9b,
601             (byte) 0x23, (byte) 0xc8, (byte) 0xa3, (byte) 0xb8, (byte) 0x33, (byte) 0x14,
602             (byte) 0xa4, (byte) 0x4d, (byte) 0x75, (byte) 0x90, (byte) 0xf3, (byte) 0xcd,
603             (byte) 0x43, (byte) 0xe5, (byte) 0x1b, (byte) 0x05, (byte) 0x1d, (byte) 0xf3,
604             (byte) 0xd0, (byte) 0xa3, (byte) 0xb7, (byte) 0x32, (byte) 0x5f, (byte) 0x79,
605             (byte) 0xdc, (byte) 0x88, (byte) 0xb8, (byte) 0x4d, (byte) 0xb3, (byte) 0xd1,
606             (byte) 0x6d, (byte) 0xf7, (byte) 0x75, (byte) 0xf3, (byte) 0xbf, (byte) 0x50,
607             (byte) 0xa1, (byte) 0xbc, (byte) 0x03, (byte) 0x64, (byte) 0x22, (byte) 0xe6,
608             (byte) 0x1a, (byte) 0xa1, (byte) 0xe1, (byte) 0x06, (byte) 0x68, (byte) 0x3b,
609             (byte) 0xbc, (byte) 0x9f, (byte) 0xd3, (byte) 0xae, (byte) 0x77, (byte) 0x5e,
610             (byte) 0x88, (byte) 0x0c, (byte) 0x5e, (byte) 0x0c, (byte) 0xb2, (byte) 0x38
611     };
612 
613     /**
614      * Generated from above and converted with:
615      *
616      * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
617      */
618     private static final byte[] FAKE_EC_USER_1 = new byte[] {
619             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x51, (byte) 0x30, (byte) 0x82,
620             (byte) 0x01, (byte) 0xba, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
621             (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
622             (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
623             (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
624             (byte) 0x00, (byte) 0x30, (byte) 0x45, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
625             (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
626             (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13,
627             (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
628             (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
629             (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74,
630             (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06,
631             (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18,
632             (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e,
633             (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64,
634             (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50,
635             (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64,
636             (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x33,
637             (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x37, (byte) 0x31, (byte) 0x36,
638             (byte) 0x33, (byte) 0x30, (byte) 0x30, (byte) 0x38, (byte) 0x5a, (byte) 0x17,
639             (byte) 0x0d, (byte) 0x32, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32,
640             (byte) 0x35, (byte) 0x31, (byte) 0x36, (byte) 0x33, (byte) 0x30, (byte) 0x30,
641             (byte) 0x38, (byte) 0x5a, (byte) 0x30, (byte) 0x62, (byte) 0x31, (byte) 0x0b,
642             (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
643             (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31,
644             (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55,
645             (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f,
646             (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61,
647             (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f,
648             (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c,
649             (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72,
650             (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57, (byte) 0x69,
651             (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73, (byte) 0x20,
652             (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c, (byte) 0x74,
653             (byte) 0x64, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
654             (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x12,
655             (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65, (byte) 0x72,
656             (byte) 0x2e, (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d, (byte) 0x70,
657             (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d,
658             (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07,
659             (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02,
660             (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
661             (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x03,
662             (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xd9, (byte) 0xcf, (byte) 0xe7,
663             (byte) 0x9b, (byte) 0x23, (byte) 0xc8, (byte) 0xa3, (byte) 0xb8, (byte) 0x33,
664             (byte) 0x14, (byte) 0xa4, (byte) 0x4d, (byte) 0x75, (byte) 0x90, (byte) 0xf3,
665             (byte) 0xcd, (byte) 0x43, (byte) 0xe5, (byte) 0x1b, (byte) 0x05, (byte) 0x1d,
666             (byte) 0xf3, (byte) 0xd0, (byte) 0xa3, (byte) 0xb7, (byte) 0x32, (byte) 0x5f,
667             (byte) 0x79, (byte) 0xdc, (byte) 0x88, (byte) 0xb8, (byte) 0x4d, (byte) 0xb3,
668             (byte) 0xd1, (byte) 0x6d, (byte) 0xf7, (byte) 0x75, (byte) 0xf3, (byte) 0xbf,
669             (byte) 0x50, (byte) 0xa1, (byte) 0xbc, (byte) 0x03, (byte) 0x64, (byte) 0x22,
670             (byte) 0xe6, (byte) 0x1a, (byte) 0xa1, (byte) 0xe1, (byte) 0x06, (byte) 0x68,
671             (byte) 0x3b, (byte) 0xbc, (byte) 0x9f, (byte) 0xd3, (byte) 0xae, (byte) 0x77,
672             (byte) 0x5e, (byte) 0x88, (byte) 0x0c, (byte) 0x5e, (byte) 0x0c, (byte) 0xb2,
673             (byte) 0x38, (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79, (byte) 0x30,
674             (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
675             (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30, (byte) 0x2c,
676             (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01,
677             (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d, (byte) 0x04,
678             (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70, (byte) 0x65,
679             (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20, (byte) 0x47,
680             (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61, (byte) 0x74,
681             (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65, (byte) 0x72,
682             (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63, (byte) 0x61,
683             (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03,
684             (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04,
685             (byte) 0x14, (byte) 0xd5, (byte) 0xc4, (byte) 0x72, (byte) 0xbd, (byte) 0xd2,
686             (byte) 0x4e, (byte) 0x90, (byte) 0x1b, (byte) 0x14, (byte) 0x32, (byte) 0xdb,
687             (byte) 0x03, (byte) 0xae, (byte) 0xfa, (byte) 0x27, (byte) 0x7d, (byte) 0x8d,
688             (byte) 0xe4, (byte) 0x80, (byte) 0x58, (byte) 0x30, (byte) 0x1f, (byte) 0x06,
689             (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18,
690             (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x5f, (byte) 0x5b,
691             (byte) 0x5e, (byte) 0xac, (byte) 0x29, (byte) 0xfa, (byte) 0xa1, (byte) 0x9f,
692             (byte) 0x9e, (byte) 0xad, (byte) 0x46, (byte) 0xe1, (byte) 0xbc, (byte) 0x20,
693             (byte) 0x72, (byte) 0xcf, (byte) 0x4a, (byte) 0xd4, (byte) 0xfa, (byte) 0xe3,
694             (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
695             (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
696             (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81,
697             (byte) 0x00, (byte) 0x43, (byte) 0x99, (byte) 0x9f, (byte) 0x67, (byte) 0x08,
698             (byte) 0x43, (byte) 0xd5, (byte) 0x6b, (byte) 0x6f, (byte) 0xd7, (byte) 0x05,
699             (byte) 0xd6, (byte) 0x75, (byte) 0x34, (byte) 0x30, (byte) 0xca, (byte) 0x20,
700             (byte) 0x47, (byte) 0x61, (byte) 0xa1, (byte) 0x89, (byte) 0xb6, (byte) 0xf1,
701             (byte) 0x49, (byte) 0x7b, (byte) 0xd9, (byte) 0xb9, (byte) 0xe8, (byte) 0x1e,
702             (byte) 0x29, (byte) 0x74, (byte) 0x0a, (byte) 0x67, (byte) 0xc0, (byte) 0x7d,
703             (byte) 0xb8, (byte) 0xe6, (byte) 0x39, (byte) 0xa8, (byte) 0x5e, (byte) 0xc3,
704             (byte) 0xb0, (byte) 0xa1, (byte) 0x30, (byte) 0x6a, (byte) 0x1f, (byte) 0x1d,
705             (byte) 0xfc, (byte) 0x11, (byte) 0x59, (byte) 0x0b, (byte) 0xb9, (byte) 0xad,
706             (byte) 0x3a, (byte) 0x4e, (byte) 0x50, (byte) 0x0a, (byte) 0x61, (byte) 0xdb,
707             (byte) 0x75, (byte) 0x6b, (byte) 0xe5, (byte) 0x3f, (byte) 0x8d, (byte) 0xde,
708             (byte) 0x28, (byte) 0x68, (byte) 0xb1, (byte) 0x29, (byte) 0x9a, (byte) 0x18,
709             (byte) 0x8a, (byte) 0xfc, (byte) 0x3f, (byte) 0x13, (byte) 0x93, (byte) 0x29,
710             (byte) 0xed, (byte) 0x22, (byte) 0x7c, (byte) 0xb4, (byte) 0x50, (byte) 0xd5,
711             (byte) 0x4d, (byte) 0x32, (byte) 0x4d, (byte) 0x42, (byte) 0x2b, (byte) 0x29,
712             (byte) 0x97, (byte) 0x86, (byte) 0xc0, (byte) 0x01, (byte) 0x00, (byte) 0x25,
713             (byte) 0xf6, (byte) 0xd3, (byte) 0x2a, (byte) 0xd8, (byte) 0xda, (byte) 0x13,
714             (byte) 0x94, (byte) 0x12, (byte) 0x78, (byte) 0x14, (byte) 0x0b, (byte) 0x51,
715             (byte) 0xc0, (byte) 0x45, (byte) 0xb4, (byte) 0x02, (byte) 0x37, (byte) 0x98,
716             (byte) 0x42, (byte) 0x3c, (byte) 0xcb, (byte) 0x2e, (byte) 0xe4, (byte) 0x38,
717             (byte) 0x69, (byte) 0x1b, (byte) 0x72, (byte) 0xf0, (byte) 0xaa, (byte) 0x89,
718             (byte) 0x7e, (byte) 0xde, (byte) 0xb2
719     };
720 
721     /**
722      * The amount of time to allow before and after expected time for variance
723      * in timing tests.
724      */
725     private static final long SLOP_TIME_MILLIS = 15000L;
726 
727     @Override
setUp()728     protected void setUp() throws Exception {
729         super.setUp();
730 
731         // Wipe any existing entries in the KeyStore
732         KeyStore ksTemp = KeyStore.getInstance("AndroidKeyStore");
733         ksTemp.load(null, null);
734         Enumeration<String> aliases = ksTemp.aliases();
735         while (aliases.hasMoreElements()) {
736             String alias = aliases.nextElement();
737             ksTemp.deleteEntry(alias);
738         }
739 
740         // Get a new instance because some tests need it uninitialized
741         mKeyStore = KeyStore.getInstance("AndroidKeyStore");
742 
743         // Use a longer timeout on watches, which are generally less performant.
744         mMaxImportDuration =
745                 getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
746                         ? LARGE_NUMBER_OF_KEYS_TEST_MAX_DURATION_WATCH
747                         : LARGE_NUMBER_OF_KEYS_TEST_MAX_DURATION;
748     }
749 
750     @Override
tearDown()751     protected void tearDown() throws Exception {
752         try {
753             KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
754             keyStore.load(null, null);
755             Enumeration<String> aliases = keyStore.aliases();
756             while (aliases.hasMoreElements()) {
757                 String alias = aliases.nextElement();
758                 keyStore.deleteEntry(alias);
759             }
760         } finally {
761             super.tearDown();
762         }
763     }
764 
generatePrivateKey(String keyType, byte[] fakeKey1)765     private PrivateKey generatePrivateKey(String keyType, byte[] fakeKey1) throws Exception {
766         KeyFactory kf = KeyFactory.getInstance(keyType);
767         return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey1));
768     }
769 
generateCertificate(byte[] fakeUser1)770     private Certificate generateCertificate(byte[] fakeUser1) throws Exception {
771         CertificateFactory cf = CertificateFactory.getInstance("X.509");
772         return cf.generateCertificate(new ByteArrayInputStream(fakeUser1));
773     }
774 
makeUserEcKey1()775     private PrivateKeyEntry makeUserEcKey1() throws Exception {
776         return new KeyStore.PrivateKeyEntry(generatePrivateKey("EC", FAKE_EC_KEY_1),
777                 new Certificate[] {
778                         generateCertificate(FAKE_EC_USER_1), generateCertificate(FAKE_EC_CA_1)
779                 });
780     }
781 
makeUserRsaKey1()782     private PrivateKeyEntry makeUserRsaKey1() throws Exception {
783         return new KeyStore.PrivateKeyEntry(generatePrivateKey("RSA", FAKE_RSA_KEY_1),
784                 new Certificate[] {
785                         generateCertificate(FAKE_RSA_USER_1), generateCertificate(FAKE_RSA_CA_1)
786                 });
787     }
788 
makeCa1()789     private Entry makeCa1() throws Exception {
790         return new KeyStore.TrustedCertificateEntry(generateCertificate(FAKE_RSA_CA_1));
791     }
792 
assertAliases(final String[] expectedAliases)793     private void assertAliases(final String[] expectedAliases) throws KeyStoreException {
794         final Enumeration<String> aliases = mKeyStore.aliases();
795         int count = 0;
796 
797         final Set<String> expectedSet = new HashSet<String>();
798         expectedSet.addAll(Arrays.asList(expectedAliases));
799 
800         while (aliases.hasMoreElements()) {
801             count++;
802             final String alias = aliases.nextElement();
803             assertTrue("The alias should be in the expected set", expectedSet.contains(alias));
804             expectedSet.remove(alias);
805         }
806         assertTrue("The expected set and actual set should be exactly equal", expectedSet.isEmpty());
807         assertEquals("There should be the correct number of keystore entries",
808                 expectedAliases.length, count);
809     }
810 
testKeyStore_Aliases_Unencrypted_Success()811     public void testKeyStore_Aliases_Unencrypted_Success() throws Exception {
812         mKeyStore.load(null, null);
813 
814         assertAliases(new String[] {});
815 
816         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
817 
818         assertAliases(new String[] { TEST_ALIAS_1 });
819 
820         mKeyStore.setEntry(TEST_ALIAS_2, makeCa1(), null);
821 
822         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
823     }
824 
testKeyStore_Aliases_NotInitialized_Unencrypted_Failure()825     public void testKeyStore_Aliases_NotInitialized_Unencrypted_Failure() throws Exception {
826         try {
827             mKeyStore.aliases();
828             fail("KeyStore should throw exception when not initialized");
829         } catch (KeyStoreException success) {
830         }
831     }
832 
testKeyStore_ContainsAliases_PrivateAndCA_Unencrypted_Success()833     public void testKeyStore_ContainsAliases_PrivateAndCA_Unencrypted_Success() throws Exception {
834         mKeyStore.load(null, null);
835 
836         assertAliases(new String[] {});
837 
838         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
839 
840         assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));
841 
842         mKeyStore.setEntry(TEST_ALIAS_2, makeCa1(), null);
843 
844         assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
845 
846         assertFalse("Should not contain unadded certificate alias",
847                 mKeyStore.containsAlias(TEST_ALIAS_3));
848     }
849 
testKeyStore_ContainsAliases_CAOnly_Unencrypted_Success()850     public void testKeyStore_ContainsAliases_CAOnly_Unencrypted_Success() throws Exception {
851         mKeyStore.load(null, null);
852 
853         mKeyStore.setEntry(TEST_ALIAS_2, makeCa1(), null);
854 
855         assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
856     }
857 
testKeyStore_ContainsAliases_NonExistent_Unencrypted_Failure()858     public void testKeyStore_ContainsAliases_NonExistent_Unencrypted_Failure() throws Exception {
859         mKeyStore.load(null, null);
860 
861         assertFalse("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_1));
862     }
863 
testKeyStore_DeleteEntry_Unencrypted_Success()864     public void testKeyStore_DeleteEntry_Unencrypted_Success() throws Exception {
865         mKeyStore.load(null, null);
866 
867         // TEST_ALIAS_1
868         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
869 
870         // TEST_ALIAS_2
871         mKeyStore.setCertificateEntry(TEST_ALIAS_2, generateCertificate(FAKE_RSA_CA_1));
872 
873         // TEST_ALIAS_3
874         mKeyStore.setCertificateEntry(TEST_ALIAS_3, generateCertificate(FAKE_RSA_CA_1));
875 
876         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
877 
878         mKeyStore.deleteEntry(TEST_ALIAS_1);
879 
880         assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
881 
882         mKeyStore.deleteEntry(TEST_ALIAS_3);
883 
884         assertAliases(new String[] { TEST_ALIAS_2 });
885 
886         mKeyStore.deleteEntry(TEST_ALIAS_2);
887 
888         assertAliases(new String[] { });
889     }
890 
testKeyStore_DeleteEntry_EmptyStore_Unencrypted_Success()891     public void testKeyStore_DeleteEntry_EmptyStore_Unencrypted_Success() throws Exception {
892         mKeyStore.load(null, null);
893 
894         // Should not throw when a non-existent entry is requested for delete.
895         mKeyStore.deleteEntry(TEST_ALIAS_1);
896     }
897 
testKeyStore_DeleteEntry_NonExistent_Unencrypted_Success()898     public void testKeyStore_DeleteEntry_NonExistent_Unencrypted_Success() throws Exception {
899         mKeyStore.load(null, null);
900 
901         // TEST_ALIAS_1
902         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
903 
904         // Should not throw when a non-existent entry is requested for delete.
905         mKeyStore.deleteEntry(TEST_ALIAS_2);
906     }
907 
testKeyStore_GetCertificate_Single_Unencrypted_Success()908     public void testKeyStore_GetCertificate_Single_Unencrypted_Success() throws Exception {
909         mKeyStore.load(null, null);
910 
911         mKeyStore.setCertificateEntry(TEST_ALIAS_1, generateCertificate(FAKE_RSA_CA_1));
912 
913         assertAliases(new String[] { TEST_ALIAS_1 });
914 
915         assertNull("Certificate should not exist in keystore",
916                 mKeyStore.getCertificate(TEST_ALIAS_2));
917 
918         Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
919 
920         assertNotNull("Retrieved certificate should not be null", retrieved);
921 
922         CertificateFactory f = CertificateFactory.getInstance("X.509");
923         Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
924 
925         assertEquals("Actual and retrieved certificates should be the same", actual, retrieved);
926     }
927 
testKeyStore_GetCertificate_NonExist_Unencrypted_Failure()928     public void testKeyStore_GetCertificate_NonExist_Unencrypted_Failure() throws Exception {
929         mKeyStore.load(null, null);
930 
931         assertNull("Certificate should not exist in keystore",
932                 mKeyStore.getCertificate(TEST_ALIAS_1));
933     }
934 
testKeyStore_GetCertificateAlias_CAEntry_Unencrypted_Success()935     public void testKeyStore_GetCertificateAlias_CAEntry_Unencrypted_Success() throws Exception {
936         mKeyStore.load(null, null);
937 
938         Certificate cert = generateCertificate(FAKE_RSA_CA_1);
939         mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
940 
941         assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
942                 mKeyStore.getCertificateAlias(cert));
943     }
944 
testKeyStore_GetCertificateAlias_PrivateKeyEntry_Unencrypted_Success()945     public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Unencrypted_Success()
946             throws Exception {
947         mKeyStore.load(null, null);
948 
949         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
950 
951         CertificateFactory f = CertificateFactory.getInstance("X.509");
952         Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
953 
954         assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
955                 mKeyStore.getCertificateAlias(actual));
956     }
957 
testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Unencrypted_Success()958     public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Unencrypted_Success()
959             throws Exception {
960         mKeyStore.load(null, null);
961 
962         Certificate actual = generateCertificate(FAKE_RSA_CA_1);
963 
964         // Insert TrustedCertificateEntry with CA name
965         mKeyStore.setCertificateEntry(TEST_ALIAS_2, actual);
966 
967         // Insert PrivateKeyEntry that uses the same CA
968         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
969 
970         assertEquals("Stored certificate alias should be found", TEST_ALIAS_2,
971                 mKeyStore.getCertificateAlias(actual));
972     }
973 
testKeyStore_GetCertificateAlias_NonExist_Empty_Unencrypted_Failure()974     public void testKeyStore_GetCertificateAlias_NonExist_Empty_Unencrypted_Failure()
975             throws Exception {
976         mKeyStore.load(null, null);
977 
978         CertificateFactory f = CertificateFactory.getInstance("X.509");
979         Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
980 
981         assertNull("Stored certificate alias should not be found",
982                 mKeyStore.getCertificateAlias(actual));
983     }
984 
testKeyStore_GetCertificateAlias_NonExist_Unencrypted_Failure()985     public void testKeyStore_GetCertificateAlias_NonExist_Unencrypted_Failure() throws Exception {
986         mKeyStore.load(null, null);
987 
988         Certificate ca = generateCertificate(FAKE_RSA_CA_1);
989 
990         // Insert TrustedCertificateEntry with CA name
991         mKeyStore.setCertificateEntry(TEST_ALIAS_1, ca);
992 
993         Certificate userCert = generateCertificate(FAKE_RSA_USER_1);
994 
995         assertNull("Stored certificate alias should be found",
996                 mKeyStore.getCertificateAlias(userCert));
997     }
998 
testKeyStore_GetCertificateChain_SingleLength_Unencrypted_Success()999     public void testKeyStore_GetCertificateChain_SingleLength_Unencrypted_Success() throws Exception {
1000         mKeyStore.load(null, null);
1001 
1002         // TEST_ALIAS_1
1003         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1004 
1005         Certificate[] expected = new Certificate[2];
1006         expected[0] = generateCertificate(FAKE_RSA_USER_1);
1007         expected[1] = generateCertificate(FAKE_RSA_CA_1);
1008 
1009         Certificate[] actual = mKeyStore.getCertificateChain(TEST_ALIAS_1);
1010 
1011         assertNotNull("Returned certificate chain should not be null", actual);
1012         assertEquals("Returned certificate chain should be correct size", expected.length,
1013                 actual.length);
1014         assertEquals("First certificate should be user certificate", expected[0], actual[0]);
1015         assertEquals("Second certificate should be CA certificate", expected[1], actual[1]);
1016 
1017         // Negative test when keystore is populated.
1018         assertNull("Stored certificate alias should not be found",
1019                 mKeyStore.getCertificateChain(TEST_ALIAS_2));
1020     }
1021 
testKeyStore_GetCertificateChain_NonExist_Unencrypted_Failure()1022     public void testKeyStore_GetCertificateChain_NonExist_Unencrypted_Failure() throws Exception {
1023         mKeyStore.load(null, null);
1024 
1025         assertNull("Stored certificate alias should not be found",
1026                 mKeyStore.getCertificateChain(TEST_ALIAS_1));
1027     }
1028 
testKeyStore_GetCreationDate_PrivateKeyEntry_Unencrypted_Success()1029     public void testKeyStore_GetCreationDate_PrivateKeyEntry_Unencrypted_Success() throws Exception {
1030         mKeyStore.load(null, null);
1031 
1032         // TEST_ALIAS_1
1033         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1034 
1035         Date now = new Date();
1036         Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
1037 
1038         Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
1039         Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
1040 
1041         assertTrue("Time should be close to current time", actual.before(expectedBefore));
1042         assertTrue("Time should be close to current time", actual.after(expectedAfter));
1043     }
1044 
testKeyStore_GetCreationDate_CAEntry_Unencrypted_Success()1045     public void testKeyStore_GetCreationDate_CAEntry_Unencrypted_Success() throws Exception {
1046         mKeyStore.load(null, null);
1047 
1048         // Insert TrustedCertificateEntry with CA name
1049         mKeyStore.setCertificateEntry(TEST_ALIAS_1, generateCertificate(FAKE_RSA_CA_1));
1050 
1051         Date now = new Date();
1052         Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
1053         assertNotNull("Certificate should be found", actual);
1054 
1055         Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
1056         Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
1057 
1058         assertTrue("Time should be close to current time", actual.before(expectedBefore));
1059         assertTrue("Time should be close to current time", actual.after(expectedAfter));
1060     }
1061 
testKeyStore_GetEntry_NullParams_Unencrypted_Success()1062     public void testKeyStore_GetEntry_NullParams_Unencrypted_Success() throws Exception {
1063         mKeyStore.load(null, null);
1064 
1065         // TEST_ALIAS_1
1066         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1067 
1068         Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1069         assertNotNull("Entry should exist", entry);
1070 
1071         assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
1072 
1073         PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1074 
1075         assertPrivateKeyEntryEquals(keyEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
1076     }
1077 
testKeyStore_GetEntry_EC_NullParams_Unencrypted_Success()1078     public void testKeyStore_GetEntry_EC_NullParams_Unencrypted_Success() throws Exception {
1079         mKeyStore.load(null, null);
1080 
1081         // TEST_ALIAS_1
1082         mKeyStore.setEntry(TEST_ALIAS_1, makeUserEcKey1(), null);
1083 
1084         Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1085         assertNotNull("Entry should exist", entry);
1086 
1087         assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
1088 
1089         PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1090 
1091         assertPrivateKeyEntryEquals(keyEntry, "EC", FAKE_EC_KEY_1, FAKE_EC_USER_1, FAKE_EC_CA_1);
1092     }
1093 
testKeyStore_GetEntry_RSA_NullParams_Unencrypted_Success()1094     public void testKeyStore_GetEntry_RSA_NullParams_Unencrypted_Success() throws Exception {
1095         mKeyStore.load(null, null);
1096 
1097         // TEST_ALIAS_1
1098         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1099 
1100         Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1101         assertNotNull("Entry should exist", entry);
1102 
1103         assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
1104 
1105         PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1106 
1107         assertPrivateKeyEntryEquals(keyEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
1108                 FAKE_RSA_CA_1);
1109     }
1110 
1111     @SuppressWarnings("unchecked")
assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, String keyType, byte[] key, byte[] cert, byte[] ca)1112     private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, String keyType, byte[] key,
1113             byte[] cert, byte[] ca) throws Exception {
1114         KeyFactory keyFact = KeyFactory.getInstance(keyType);
1115         PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(key));
1116 
1117         CertificateFactory certFact = CertificateFactory.getInstance("X.509");
1118         Certificate expectedCert = certFact.generateCertificate(new ByteArrayInputStream(cert));
1119 
1120         final Collection<Certificate> expectedChain;
1121         if (ca != null) {
1122             expectedChain = (Collection<Certificate>) certFact
1123                     .generateCertificates(new ByteArrayInputStream(ca));
1124         } else {
1125             expectedChain = null;
1126         }
1127 
1128         assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, expectedChain);
1129     }
1130 
assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey, Certificate expectedCert, Collection<Certificate> expectedChain)1131     private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey,
1132             Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception {
1133         final PrivateKey privKey = keyEntry.getPrivateKey();
1134         final PublicKey pubKey = keyEntry.getCertificate().getPublicKey();
1135 
1136         if (expectedKey instanceof ECKey) {
1137             assertTrue("Returned PrivateKey " + privKey.getClass() + " should be instanceof ECKey",
1138                     privKey instanceof ECKey);
1139             assertEquals("Returned PrivateKey should be what we inserted",
1140                     ((ECKey) expectedKey).getParams().getCurve(),
1141                     ((ECKey) privKey).getParams().getCurve());
1142         } else if (expectedKey instanceof RSAKey) {
1143             assertTrue("Returned PrivateKey " + privKey.getClass() + " should be instanceof RSAKey",
1144                     privKey instanceof RSAKey);
1145             assertEquals("Returned PrivateKey should be what we inserted",
1146                     ((RSAKey) expectedKey).getModulus(),
1147                     ((RSAKey) privKey).getModulus());
1148         }
1149 
1150         assertNull("getFormat() should return null", privKey.getFormat());
1151         assertNull("getEncoded() should return null", privKey.getEncoded());
1152 
1153         assertEquals("Public keys should be in X.509 format", "X.509", pubKey.getFormat());
1154         assertNotNull("Public keys should be encodable", pubKey.getEncoded());
1155 
1156         assertEquals("Returned Certificate should be what we inserted", expectedCert,
1157                 keyEntry.getCertificate());
1158 
1159         Certificate[] actualChain = keyEntry.getCertificateChain();
1160 
1161         assertEquals("First certificate in chain should be user cert", expectedCert, actualChain[0]);
1162 
1163         if (expectedChain == null) {
1164             assertEquals("Certificate chain should not include CAs", 1, actualChain.length);
1165         } else {
1166             assertEquals("Chains should be the same size", expectedChain.size() + 1,
1167                     actualChain.length);
1168             int i = 1;
1169             final Iterator<Certificate> it = expectedChain.iterator();
1170             while (it.hasNext() && i < actualChain.length) {
1171                 assertEquals("CA chain certificate should equal what we put in", it.next(),
1172                         actualChain[i++]);
1173             }
1174         }
1175     }
1176 
testKeyStore_GetEntry_Nonexistent_NullParams_Unencrypted_Failure()1177     public void testKeyStore_GetEntry_Nonexistent_NullParams_Unencrypted_Failure() throws Exception {
1178         mKeyStore.load(null, null);
1179 
1180         assertNull("A non-existent entry should return null",
1181                 mKeyStore.getEntry(TEST_ALIAS_1, null));
1182     }
1183 
testKeyStore_GetKey_NoPassword_Unencrypted_Success()1184     public void testKeyStore_GetKey_NoPassword_Unencrypted_Success() throws Exception {
1185         mKeyStore.load(null, null);
1186 
1187         // TEST_ALIAS_1
1188         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1189 
1190         Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
1191         assertNotNull("Key should exist", key);
1192 
1193         assertTrue("Should be a PrivateKey", key instanceof PrivateKey);
1194         assertTrue("Should be a RSAKey", key instanceof RSAKey);
1195 
1196         RSAKey actualKey = (RSAKey) key;
1197 
1198         KeyFactory keyFact = KeyFactory.getInstance("RSA");
1199         PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1200 
1201         assertEquals("Inserted key should be same as retrieved key",
1202                 ((RSAKey) expectedKey).getModulus(), actualKey.getModulus());
1203     }
1204 
testKeyStore_GetKey_Certificate_Unencrypted_Failure()1205     public void testKeyStore_GetKey_Certificate_Unencrypted_Failure() throws Exception {
1206         mKeyStore.load(null, null);
1207 
1208         // Insert TrustedCertificateEntry with CA name
1209         mKeyStore.setCertificateEntry(TEST_ALIAS_1, generateCertificate(FAKE_RSA_CA_1));
1210 
1211         assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
1212     }
1213 
testKeyStore_GetKey_NonExistent_Unencrypted_Failure()1214     public void testKeyStore_GetKey_NonExistent_Unencrypted_Failure() throws Exception {
1215         mKeyStore.load(null, null);
1216 
1217         assertNull("A non-existent entry should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
1218     }
1219 
testKeyStore_GetProvider_Unencrypted_Success()1220     public void testKeyStore_GetProvider_Unencrypted_Success() throws Exception {
1221         assertEquals("AndroidKeyStore", mKeyStore.getProvider().getName());
1222     }
1223 
testKeyStore_GetType_Unencrypted_Success()1224     public void testKeyStore_GetType_Unencrypted_Success() throws Exception {
1225         assertEquals("AndroidKeyStore", mKeyStore.getType());
1226     }
1227 
testKeyStore_IsCertificateEntry_CA_Unencrypted_Success()1228     public void testKeyStore_IsCertificateEntry_CA_Unencrypted_Success() throws Exception {
1229         mKeyStore.load(null, null);
1230 
1231         // Insert TrustedCertificateEntry with CA name
1232         mKeyStore.setCertificateEntry(TEST_ALIAS_1, generateCertificate(FAKE_RSA_CA_1));
1233 
1234         assertTrue("Should return true for CA certificate",
1235                 mKeyStore.isCertificateEntry(TEST_ALIAS_1));
1236     }
1237 
testKeyStore_IsCertificateEntry_PrivateKey_Unencrypted_Failure()1238     public void testKeyStore_IsCertificateEntry_PrivateKey_Unencrypted_Failure() throws Exception {
1239         mKeyStore.load(null, null);
1240 
1241         // TEST_ALIAS_1
1242         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1243 
1244         assertFalse("Should return false for PrivateKeyEntry",
1245                 mKeyStore.isCertificateEntry(TEST_ALIAS_1));
1246     }
1247 
testKeyStore_IsCertificateEntry_NonExist_Unencrypted_Failure()1248     public void testKeyStore_IsCertificateEntry_NonExist_Unencrypted_Failure() throws Exception {
1249         mKeyStore.load(null, null);
1250 
1251         assertFalse("Should return false for non-existent entry",
1252                 mKeyStore.isCertificateEntry(TEST_ALIAS_1));
1253     }
1254 
testKeyStore_IsKeyEntry_PrivateKey_Unencrypted_Success()1255     public void testKeyStore_IsKeyEntry_PrivateKey_Unencrypted_Success() throws Exception {
1256         mKeyStore.load(null, null);
1257 
1258         // TEST_ALIAS_1
1259         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1260 
1261         assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1));
1262     }
1263 
testKeyStore_IsKeyEntry_CA_Unencrypted_Failure()1264     public void testKeyStore_IsKeyEntry_CA_Unencrypted_Failure() throws Exception {
1265         mKeyStore.load(null, null);
1266 
1267         mKeyStore.setCertificateEntry(TEST_ALIAS_1, generateCertificate(FAKE_RSA_CA_1));
1268 
1269         assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1));
1270     }
1271 
testKeyStore_IsKeyEntry_NonExist_Unencrypted_Failure()1272     public void testKeyStore_IsKeyEntry_NonExist_Unencrypted_Failure() throws Exception {
1273         mKeyStore.load(null, null);
1274 
1275         assertFalse("Should return false for non-existent entry",
1276                 mKeyStore.isKeyEntry(TEST_ALIAS_1));
1277     }
1278 
testKeyStore_SetCertificate_CA_Unencrypted_Success()1279     public void testKeyStore_SetCertificate_CA_Unencrypted_Success() throws Exception {
1280         final Certificate actual = generateCertificate(FAKE_RSA_CA_1);
1281 
1282         mKeyStore.load(null, null);
1283 
1284         mKeyStore.setCertificateEntry(TEST_ALIAS_1, actual);
1285         assertAliases(new String[] { TEST_ALIAS_1 });
1286 
1287         Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
1288 
1289         assertEquals("Retrieved certificate should be the same as the one inserted", actual,
1290                 retrieved);
1291     }
1292 
testKeyStore_SetCertificate_CAExists_Overwrite_Unencrypted_Success()1293     public void testKeyStore_SetCertificate_CAExists_Overwrite_Unencrypted_Success()
1294             throws Exception {
1295         mKeyStore.load(null, null);
1296 
1297         mKeyStore.setCertificateEntry(TEST_ALIAS_1, generateCertificate(FAKE_RSA_CA_1));
1298 
1299         assertAliases(new String[] { TEST_ALIAS_1 });
1300 
1301         final Certificate cert = generateCertificate(FAKE_RSA_CA_1);
1302 
1303         // TODO have separate FAKE_CA for second test
1304         mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
1305 
1306         assertAliases(new String[] { TEST_ALIAS_1 });
1307     }
1308 
testKeyStore_SetCertificate_PrivateKeyExists_Unencrypted_Failure()1309     public void testKeyStore_SetCertificate_PrivateKeyExists_Unencrypted_Failure() throws Exception {
1310         mKeyStore.load(null, null);
1311 
1312         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1313 
1314         assertAliases(new String[] { TEST_ALIAS_1 });
1315 
1316         final Certificate cert = generateCertificate(FAKE_RSA_CA_1);
1317 
1318         try {
1319             mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
1320             fail("Should throw when trying to overwrite a PrivateKey entry with a Certificate");
1321         } catch (KeyStoreException success) {
1322         }
1323     }
1324 
testKeyStore_SetEntry_PrivateKeyEntry_Unencrypted_Success()1325     public void testKeyStore_SetEntry_PrivateKeyEntry_Unencrypted_Success() throws Exception {
1326         mKeyStore.load(null, null);
1327 
1328         KeyFactory keyFact = KeyFactory.getInstance("RSA");
1329         PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1330 
1331         final CertificateFactory f = CertificateFactory.getInstance("X.509");
1332 
1333         final Certificate[] expectedChain = new Certificate[2];
1334         expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1335         expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1336 
1337         PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1338 
1339         mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1340 
1341         Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1342         assertNotNull("Retrieved entry should exist", actualEntry);
1343 
1344         assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1345                 actualEntry instanceof PrivateKeyEntry);
1346 
1347         PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1348 
1349         assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
1350     }
1351 
testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Unencrypted_Success()1352     public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Unencrypted_Success()
1353             throws Exception {
1354         mKeyStore.load(null, null);
1355 
1356         final KeyFactory keyFact = KeyFactory.getInstance("RSA");
1357         final CertificateFactory f = CertificateFactory.getInstance("X.509");
1358 
1359         // Start with PrivateKeyEntry
1360         {
1361             PrivateKey expectedKey = keyFact
1362                     .generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1363 
1364             final Certificate[] expectedChain = new Certificate[2];
1365             expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1366             expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1367 
1368             PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1369 
1370             mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1371 
1372             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1373             assertNotNull("Retrieved entry should exist", actualEntry);
1374 
1375             assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1376                     actualEntry instanceof PrivateKeyEntry);
1377 
1378             PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1379 
1380             assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
1381                     FAKE_RSA_CA_1);
1382         }
1383 
1384         // TODO make entirely new test vector for the overwrite
1385         // Replace with PrivateKeyEntry
1386         {
1387             PrivateKey expectedKey = keyFact
1388                     .generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1389 
1390             final Certificate[] expectedChain = new Certificate[2];
1391             expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1392             expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1393 
1394             PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
1395 
1396             mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
1397 
1398             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1399             assertNotNull("Retrieved entry should exist", actualEntry);
1400 
1401             assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1402                     actualEntry instanceof PrivateKeyEntry);
1403 
1404             PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1405 
1406             assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
1407                     FAKE_RSA_CA_1);
1408         }
1409     }
1410 
testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Unencrypted_Success()1411     public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Unencrypted_Success()
1412             throws Exception {
1413         mKeyStore.load(null, null);
1414 
1415         final CertificateFactory f = CertificateFactory.getInstance("X.509");
1416 
1417         // Start with TrustedCertificateEntry
1418         {
1419             final Certificate caCert = f
1420                     .generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1421 
1422             TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1423             mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1424 
1425             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1426             assertNotNull("Retrieved entry should exist", actualEntry);
1427             assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1428                     actualEntry instanceof TrustedCertificateEntry);
1429             TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1430             assertEquals("Stored and retrieved certificates should be the same",
1431                     expectedCertEntry.getTrustedCertificate(),
1432                     actualCertEntry.getTrustedCertificate());
1433         }
1434 
1435         // Replace with PrivateKeyEntry
1436         {
1437             KeyFactory keyFact = KeyFactory.getInstance("RSA");
1438             PrivateKey expectedKey = keyFact
1439                     .generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1440             final Certificate[] expectedChain = new Certificate[2];
1441             expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1442             expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1443 
1444             PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1445 
1446             mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1447 
1448             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1449             assertNotNull("Retrieved entry should exist", actualEntry);
1450             assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1451                     actualEntry instanceof PrivateKeyEntry);
1452 
1453             PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1454             assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
1455                     FAKE_RSA_CA_1);
1456         }
1457     }
1458 
testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Unencrypted_Success()1459     public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Unencrypted_Success()
1460             throws Exception {
1461         mKeyStore.load(null, null);
1462 
1463         final CertificateFactory f = CertificateFactory.getInstance("X.509");
1464 
1465         final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1466 
1467         // Start with PrivateKeyEntry
1468         {
1469             KeyFactory keyFact = KeyFactory.getInstance("RSA");
1470             PrivateKey expectedKey = keyFact
1471                     .generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1472             final Certificate[] expectedChain = new Certificate[2];
1473             expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1474             expectedChain[1] = caCert;
1475 
1476             PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1477 
1478             mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1479 
1480             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1481             assertNotNull("Retrieved entry should exist", actualEntry);
1482             assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1483                     actualEntry instanceof PrivateKeyEntry);
1484 
1485             PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1486             assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
1487                     FAKE_RSA_CA_1);
1488         }
1489 
1490         // Replace with TrustedCertificateEntry
1491         {
1492             TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1493             mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1494 
1495             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1496             assertNotNull("Retrieved entry should exist", actualEntry);
1497             assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1498                     actualEntry instanceof TrustedCertificateEntry);
1499             TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1500             assertEquals("Stored and retrieved certificates should be the same",
1501                     expectedCertEntry.getTrustedCertificate(),
1502                     actualCertEntry.getTrustedCertificate());
1503         }
1504     }
1505 
testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Unencrypted_Success()1506     public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Unencrypted_Success()
1507             throws Exception {
1508         mKeyStore.load(null, null);
1509 
1510         final CertificateFactory f = CertificateFactory.getInstance("X.509");
1511 
1512         final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1513 
1514         // Start with PrivateKeyEntry
1515         {
1516             KeyFactory keyFact = KeyFactory.getInstance("RSA");
1517             PrivateKey expectedKey = keyFact
1518                     .generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1519             final Certificate[] expectedChain = new Certificate[2];
1520             expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1521             expectedChain[1] = caCert;
1522 
1523             PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1524 
1525             mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1526 
1527             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1528             assertNotNull("Retrieved entry should exist", actualEntry);
1529             assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1530                     actualEntry instanceof PrivateKeyEntry);
1531 
1532             PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1533             assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
1534                     FAKE_RSA_CA_1);
1535         }
1536 
1537         // Replace with PrivateKeyEntry that has no chain
1538         {
1539             KeyFactory keyFact = KeyFactory.getInstance("RSA");
1540             PrivateKey expectedKey = keyFact
1541                     .generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1542             final Certificate[] expectedChain = new Certificate[1];
1543             expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1544 
1545             PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
1546 
1547             mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
1548 
1549             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1550             assertNotNull("Retrieved entry should exist", actualEntry);
1551             assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1552                     actualEntry instanceof PrivateKeyEntry);
1553 
1554             PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
1555             assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
1556                     null);
1557         }
1558     }
1559 
testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Unencrypted_Success()1560     public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Unencrypted_Success()
1561             throws Exception {
1562         mKeyStore.load(null, null);
1563 
1564         final CertificateFactory f = CertificateFactory.getInstance("X.509");
1565 
1566         // Insert TrustedCertificateEntry
1567         {
1568             final Certificate caCert = f
1569                     .generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1570 
1571             TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
1572             mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
1573 
1574             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1575             assertNotNull("Retrieved entry should exist", actualEntry);
1576             assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1577                     actualEntry instanceof TrustedCertificateEntry);
1578             TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
1579             assertEquals("Stored and retrieved certificates should be the same",
1580                     expectedCertEntry.getTrustedCertificate(),
1581                     actualCertEntry.getTrustedCertificate());
1582         }
1583 
1584         // Replace with TrustedCertificateEntry of USER
1585         {
1586             final Certificate userCert = f.generateCertificate(new ByteArrayInputStream(
1587                     FAKE_RSA_USER_1));
1588 
1589             TrustedCertificateEntry expectedUserEntry = new TrustedCertificateEntry(userCert);
1590             mKeyStore.setEntry(TEST_ALIAS_1, expectedUserEntry, null);
1591 
1592             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1593             assertNotNull("Retrieved entry should exist", actualEntry);
1594             assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
1595                     actualEntry instanceof TrustedCertificateEntry);
1596             TrustedCertificateEntry actualUserEntry = (TrustedCertificateEntry) actualEntry;
1597             assertEquals("Stored and retrieved certificates should be the same",
1598                     expectedUserEntry.getTrustedCertificate(),
1599                     actualUserEntry.getTrustedCertificate());
1600         }
1601     }
1602 
testKeyStore_SetKeyEntry_ProtectedKey_Unencrypted_Failure()1603     public void testKeyStore_SetKeyEntry_ProtectedKey_Unencrypted_Failure() throws Exception {
1604         mKeyStore.load(null, null);
1605 
1606         final CertificateFactory f = CertificateFactory.getInstance("X.509");
1607 
1608         final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1609 
1610         KeyFactory keyFact = KeyFactory.getInstance("RSA");
1611         PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1612         final Certificate[] chain = new Certificate[2];
1613         chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1614         chain[1] = caCert;
1615 
1616         try {
1617             mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, "foo".toCharArray(), chain);
1618             fail("Should fail when a password is specified");
1619         } catch (KeyStoreException success) {
1620         }
1621     }
1622 
testKeyStore_SetKeyEntry_Unencrypted_Success()1623     public void testKeyStore_SetKeyEntry_Unencrypted_Success() throws Exception {
1624         mKeyStore.load(null, null);
1625 
1626         final CertificateFactory f = CertificateFactory.getInstance("X.509");
1627 
1628         final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1629 
1630         KeyFactory keyFact = KeyFactory.getInstance("RSA");
1631         PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1632         final Certificate[] chain = new Certificate[2];
1633         chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1634         chain[1] = caCert;
1635 
1636         mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1637 
1638         Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1639         assertNotNull("Retrieved entry should exist", actualEntry);
1640 
1641         assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1642                 actualEntry instanceof PrivateKeyEntry);
1643 
1644         PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1645 
1646         assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
1647     }
1648 
testKeyStore_SetKeyEntry_Replaced_Unencrypted_Success()1649     public void testKeyStore_SetKeyEntry_Replaced_Unencrypted_Success() throws Exception {
1650         mKeyStore.load(null, null);
1651 
1652         final CertificateFactory f = CertificateFactory.getInstance("X.509");
1653 
1654         final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
1655 
1656         // Insert initial key
1657         {
1658             KeyFactory keyFact = KeyFactory.getInstance("RSA");
1659             PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1660             final Certificate[] chain = new Certificate[2];
1661             chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1662             chain[1] = caCert;
1663 
1664             mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1665 
1666             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1667             assertNotNull("Retrieved entry should exist", actualEntry);
1668 
1669             assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1670                     actualEntry instanceof PrivateKeyEntry);
1671 
1672             PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1673 
1674             assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
1675                     FAKE_RSA_CA_1);
1676         }
1677 
1678         // TODO make a separate key
1679         // Replace key
1680         {
1681             KeyFactory keyFact = KeyFactory.getInstance("RSA");
1682             PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1683             final Certificate[] chain = new Certificate[2];
1684             chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
1685             chain[1] = caCert;
1686 
1687             mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
1688 
1689             Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1690             assertNotNull("Retrieved entry should exist", actualEntry);
1691 
1692             assertTrue("Retrieved entry should be of type PrivateKeyEntry",
1693                     actualEntry instanceof PrivateKeyEntry);
1694 
1695             PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
1696 
1697             assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
1698                     FAKE_RSA_CA_1);
1699         }
1700     }
1701 
testKeyStore_SetKeyEntry_ReplacedChain_Unencrypted_Success()1702     public void testKeyStore_SetKeyEntry_ReplacedChain_Unencrypted_Success() throws Exception {
1703         mKeyStore.load(null, null);
1704 
1705         // Create key #1
1706         {
1707             KeyStore.PrivateKeyEntry privEntry = makeUserRsaKey1();
1708             mKeyStore.setEntry(TEST_ALIAS_1, privEntry, null);
1709 
1710             Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1711 
1712             assertTrue(entry instanceof PrivateKeyEntry);
1713 
1714             PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1715 
1716             ArrayList<Certificate> chain = new ArrayList<Certificate>();
1717             chain.add(generateCertificate(FAKE_RSA_CA_1));
1718             assertPrivateKeyEntryEquals(keyEntry, privEntry.getPrivateKey(),
1719                     privEntry.getCertificate(), chain);
1720         }
1721 
1722         // Replace key #1 with new chain
1723         {
1724             Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
1725 
1726             assertTrue(key instanceof PrivateKey);
1727 
1728             PrivateKey expectedKey = (PrivateKey) key;
1729 
1730             Certificate expectedCert = generateCertificate(FAKE_RSA_USER_1);
1731 
1732             mKeyStore.setKeyEntry(TEST_ALIAS_1, expectedKey, null,
1733                     new Certificate[] { expectedCert });
1734 
1735             Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1736 
1737             assertTrue(entry instanceof PrivateKeyEntry);
1738 
1739             PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
1740 
1741             assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
1742         }
1743     }
1744 
testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Unencrypted_Failure()1745     public void testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Unencrypted_Failure()
1746             throws Exception {
1747         mKeyStore.load(null, null);
1748 
1749         // Create key #1
1750         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1751 
1752         // Create key #2
1753         mKeyStore.setEntry(TEST_ALIAS_2, makeUserRsaKey1(), null);
1754 
1755 
1756         // Replace key #1 with key #2
1757         {
1758             Key key1 = mKeyStore.getKey(TEST_ALIAS_2, null);
1759 
1760             Certificate cert = generateCertificate(FAKE_RSA_USER_1);
1761 
1762             try {
1763                 mKeyStore.setKeyEntry(TEST_ALIAS_1, key1, null, new Certificate[] { cert });
1764                 fail("Should not allow setting of KeyEntry with wrong PrivaetKey");
1765             } catch (KeyStoreException success) {
1766             }
1767         }
1768     }
1769 
testKeyStore_SetKeyEntry_ReplacedWithSame_UnencryptedToUnencrypted_Failure()1770     public void testKeyStore_SetKeyEntry_ReplacedWithSame_UnencryptedToUnencrypted_Failure()
1771             throws Exception {
1772         mKeyStore.load(null, null);
1773 
1774         // Create key #1
1775         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1776 
1777         // Replace with same
1778         Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
1779         mKeyStore.setEntry(TEST_ALIAS_1, entry, null);
1780     }
1781 
1782     /*
1783      * Replacing an existing secret key with itself should be a no-op.
1784      */
testKeyStore_SetKeyEntry_ReplacedWithSameGeneratedSecretKey()1785     public void testKeyStore_SetKeyEntry_ReplacedWithSameGeneratedSecretKey()
1786             throws Exception {
1787         final String plaintext = "My awesome plaintext message!";
1788         final String algorithm = "AES/GCM/NoPadding";
1789 
1790         final KeyGenerator generator = KeyGenerator.getInstance("AES", "AndroidKeyStore");
1791         final KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(TEST_ALIAS_1,
1792                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
1793                 .setKeySize(256)
1794                 .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
1795                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
1796                 .build();
1797         generator.init(spec);
1798         final SecretKey key = generator.generateKey();
1799 
1800         Cipher cipher = Cipher.getInstance(algorithm);
1801         cipher.init(Cipher.ENCRYPT_MODE, key);
1802         AlgorithmParameters params = cipher.getParameters();
1803         final byte[] ciphertext = cipher.doFinal(plaintext.getBytes());
1804 
1805         mKeyStore.load(null, null);
1806 
1807         // This should succeed.
1808         mKeyStore.setKeyEntry(TEST_ALIAS_1, key, null, null);
1809         // And it should not change the key under TEST_ALIAS_1. And what better way to test
1810         // then to use it on some cipher text generated with that key.
1811         final Key key2 = mKeyStore.getKey(TEST_ALIAS_1, null);
1812         cipher = Cipher.getInstance(algorithm);
1813         cipher.init(Cipher.DECRYPT_MODE, key2, params);
1814         byte[] plaintext2 = cipher.doFinal(ciphertext);
1815         Assert.assertArrayEquals("The plaintext2 should match the original plaintext.",
1816                 plaintext2, plaintext.getBytes());
1817     }
1818 
testKeyStore_Size_Unencrypted_Success()1819     public void testKeyStore_Size_Unencrypted_Success() throws Exception {
1820         mKeyStore.load(null, null);
1821 
1822         mKeyStore.setCertificateEntry(TEST_ALIAS_1, generateCertificate(FAKE_RSA_CA_1));
1823 
1824         assertEquals("The keystore size should match expected", 1, mKeyStore.size());
1825         assertAliases(new String[] { TEST_ALIAS_1 });
1826 
1827         mKeyStore.setCertificateEntry(TEST_ALIAS_2, generateCertificate(FAKE_RSA_CA_1));
1828 
1829         assertEquals("The keystore size should match expected", 2, mKeyStore.size());
1830         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
1831 
1832         mKeyStore.setEntry(TEST_ALIAS_3, makeUserRsaKey1(), null);
1833 
1834         assertEquals("The keystore size should match expected", 3, mKeyStore.size());
1835         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
1836 
1837         mKeyStore.deleteEntry(TEST_ALIAS_1);
1838 
1839         assertEquals("The keystore size should match expected", 2, mKeyStore.size());
1840         assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
1841 
1842         mKeyStore.deleteEntry(TEST_ALIAS_3);
1843 
1844         assertEquals("The keystore size should match expected", 1, mKeyStore.size());
1845         assertAliases(new String[] { TEST_ALIAS_2 });
1846     }
1847 
testKeyStore_Store_LoadStoreParam_Unencrypted_Failure()1848     public void testKeyStore_Store_LoadStoreParam_Unencrypted_Failure() throws Exception {
1849         mKeyStore.load(null, null);
1850 
1851         try {
1852             mKeyStore.store(null);
1853             fail("Should throw UnsupportedOperationException when trying to store");
1854         } catch (UnsupportedOperationException success) {
1855         }
1856     }
1857 
testKeyStore_Load_InputStreamSupplied_Unencrypted_Failure()1858     public void testKeyStore_Load_InputStreamSupplied_Unencrypted_Failure() throws Exception {
1859         byte[] buf = "FAKE KEYSTORE".getBytes();
1860         ByteArrayInputStream is = new ByteArrayInputStream(buf);
1861 
1862         try {
1863             mKeyStore.load(is, null);
1864             fail("Should throw IllegalArgumentException when InputStream is supplied");
1865         } catch (IllegalArgumentException success) {
1866         }
1867     }
1868 
testKeyStore_Load_PasswordSupplied_Unencrypted_Failure()1869     public void testKeyStore_Load_PasswordSupplied_Unencrypted_Failure() throws Exception {
1870         try {
1871             mKeyStore.load(null, "password".toCharArray());
1872             fail("Should throw IllegalArgumentException when password is supplied");
1873         } catch (IllegalArgumentException success) {
1874         }
1875     }
1876 
testKeyStore_Store_OutputStream_Unencrypted_Failure()1877     public void testKeyStore_Store_OutputStream_Unencrypted_Failure() throws Exception {
1878         mKeyStore.load(null, null);
1879 
1880         OutputStream sink = new ByteArrayOutputStream();
1881         try {
1882             mKeyStore.store(sink, null);
1883             fail("Should throw UnsupportedOperationException when trying to store");
1884         } catch (UnsupportedOperationException success) {
1885         }
1886 
1887         try {
1888             mKeyStore.store(sink, "blah".toCharArray());
1889             fail("Should throw UnsupportedOperationException when trying to store");
1890         } catch (UnsupportedOperationException success) {
1891         }
1892     }
1893 
testKeyStore_KeyOperations_Wrap_Unencrypted_Success()1894     public void testKeyStore_KeyOperations_Wrap_Unencrypted_Success() throws Exception {
1895         mKeyStore.load(null, null);
1896 
1897         mKeyStore.setEntry(TEST_ALIAS_1, makeUserRsaKey1(), null);
1898 
1899         // Test key usage
1900         Entry e = mKeyStore.getEntry(TEST_ALIAS_1, null);
1901         assertNotNull(e);
1902         assertTrue(e instanceof PrivateKeyEntry);
1903 
1904         PrivateKeyEntry privEntry = (PrivateKeyEntry) e;
1905         PrivateKey privKey = privEntry.getPrivateKey();
1906         assertNotNull(privKey);
1907 
1908         PublicKey pubKey = privEntry.getCertificate().getPublicKey();
1909 
1910         Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
1911         c.init(Cipher.WRAP_MODE, pubKey);
1912 
1913         byte[] expectedKey = new byte[] {
1914                 0x00, 0x05, (byte) 0xAA, (byte) 0x0A5, (byte) 0xFF, 0x55, 0x0A
1915         };
1916 
1917         SecretKey expectedSecret = new TransparentSecretKey(expectedKey, "AES");
1918 
1919         byte[] wrappedExpected = c.wrap(expectedSecret);
1920 
1921         c.init(Cipher.UNWRAP_MODE, privKey);
1922         SecretKey actualSecret = (SecretKey) c.unwrap(wrappedExpected, "AES", Cipher.SECRET_KEY);
1923 
1924         assertEquals(Arrays.toString(expectedSecret.getEncoded()),
1925                 Arrays.toString(actualSecret.getEncoded()));
1926     }
1927 
testKeyStore_Encrypting_RSA_NONE_NOPADDING()1928     public void testKeyStore_Encrypting_RSA_NONE_NOPADDING() throws Exception {
1929 
1930         String alias = "MyKey";
1931         KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
1932         assertNotNull(ks);
1933         ks.load(null);
1934 
1935         Calendar cal = Calendar.getInstance();
1936         cal.set(1944, 5, 6);
1937         Date now = cal.getTime();
1938         cal.clear();
1939 
1940         cal.set(1945, 8, 2);
1941         Date end = cal.getTime();
1942 
1943         KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
1944         assertNotNull(kpg);
1945         kpg.initialize(new KeyPairGeneratorSpec.Builder(mContext)
1946                 .setAlias(alias)
1947                 .setStartDate(now)
1948                 .setEndDate(end)
1949                 .setSerialNumber(BigInteger.valueOf(1))
1950                 .setSubject(new X500Principal("CN=test1"))
1951                 .build());
1952 
1953         kpg.generateKeyPair();
1954 
1955         PrivateKey privateKey = (PrivateKey) ks.getKey(alias, null);
1956         assertNotNull(privateKey);
1957         PublicKey publicKey = ks.getCertificate(alias).getPublicKey();
1958         assertNotNull(publicKey);
1959         String cipher = privateKey.getAlgorithm() + "/NONE/NOPADDING";
1960         Cipher encrypt = Cipher.getInstance(cipher);
1961         assertNotNull(encrypt);
1962         encrypt.init(Cipher.ENCRYPT_MODE, privateKey);
1963 
1964         int modulusSizeBytes = (((RSAKey) publicKey).getModulus().bitLength() + 7) / 8;
1965         byte[] plainText = new byte[modulusSizeBytes];
1966         Arrays.fill(plainText, (byte) 0xFF);
1967 
1968         // We expect a BadPaddingException here as the message size (plaintext)
1969         // is bigger than the modulus.
1970         try {
1971             encrypt.doFinal(plainText);
1972             fail("Expected BadPaddingException or IllegalBlockSizeException");
1973         } catch (BadPaddingException e) {
1974             // pass on exception as it is expected
1975         } catch (IllegalBlockSizeException e) {
1976             // pass on exception as it is expected
1977         }
1978     }
1979 
testKeyStore_PrivateKeyEntry_RSA_PublicKeyWorksWithCrypto()1980     public void testKeyStore_PrivateKeyEntry_RSA_PublicKeyWorksWithCrypto()
1981             throws Exception {
1982         mKeyStore.load(null, null);
1983         mKeyStore.setKeyEntry(TEST_ALIAS_2,
1984                 KeyFactory.getInstance("RSA").generatePrivate(
1985                         new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1)),
1986                 null, // no password (it's not even supported)
1987                 new Certificate[] {generateCertificate(FAKE_RSA_USER_1)});
1988         PublicKey publicKey = mKeyStore.getCertificate(TEST_ALIAS_2).getPublicKey();
1989         assertNotNull(publicKey);
1990 
1991         Signature.getInstance("SHA256withRSA").initVerify(publicKey);
1992         Signature.getInstance("NONEwithRSA").initVerify(publicKey);
1993         Signature.getInstance("SHA256withRSA/PSS").initVerify(publicKey);
1994 
1995         Cipher.getInstance("RSA/ECB/PKCS1Padding").init(Cipher.ENCRYPT_MODE, publicKey);
1996         Cipher.getInstance("RSA/ECB/NoPadding").init(Cipher.ENCRYPT_MODE, publicKey);
1997         Cipher.getInstance("RSA/ECB/OAEPPadding").init(Cipher.ENCRYPT_MODE, publicKey);
1998     }
1999 
testKeyStore_PrivateKeyEntry_EC_PublicKeyWorksWithCrypto()2000     public void testKeyStore_PrivateKeyEntry_EC_PublicKeyWorksWithCrypto()
2001             throws Exception {
2002         mKeyStore.load(null, null);
2003         mKeyStore.setKeyEntry(TEST_ALIAS_1,
2004                 KeyFactory.getInstance("EC").generatePrivate(
2005                         new PKCS8EncodedKeySpec(FAKE_EC_KEY_1)),
2006                 null, // no password (it's not even supported)
2007                 new Certificate[] {generateCertificate(FAKE_EC_USER_1)});
2008         PublicKey publicKey = mKeyStore.getCertificate(TEST_ALIAS_1).getPublicKey();
2009         assertNotNull(publicKey);
2010 
2011         Signature.getInstance("SHA256withECDSA").initVerify(publicKey);
2012         Signature.getInstance("NONEwithECDSA").initVerify(publicKey);
2013     }
2014 
testKeyStore_TrustedCertificateEntry_RSA_PublicKeyWorksWithCrypto()2015     public void testKeyStore_TrustedCertificateEntry_RSA_PublicKeyWorksWithCrypto()
2016             throws Exception {
2017         mKeyStore.load(null, null);
2018         mKeyStore.setCertificateEntry(TEST_ALIAS_2, generateCertificate(FAKE_RSA_USER_1));
2019         PublicKey publicKey = mKeyStore.getCertificate(TEST_ALIAS_2).getPublicKey();
2020         assertNotNull(publicKey);
2021 
2022         Signature.getInstance("SHA256withRSA").initVerify(publicKey);
2023         Signature.getInstance("NONEwithRSA").initVerify(publicKey);
2024 
2025         Cipher.getInstance("RSA/ECB/PKCS1Padding").init(Cipher.ENCRYPT_MODE, publicKey);
2026         Cipher.getInstance("RSA/ECB/NoPadding").init(Cipher.ENCRYPT_MODE, publicKey);
2027     }
2028 
testKeyStore_TrustedCertificateEntry_EC_PublicKeyWorksWithCrypto()2029     public void testKeyStore_TrustedCertificateEntry_EC_PublicKeyWorksWithCrypto()
2030             throws Exception {
2031         mKeyStore.load(null, null);
2032         mKeyStore.setCertificateEntry(TEST_ALIAS_1, generateCertificate(FAKE_EC_USER_1));
2033         PublicKey publicKey = mKeyStore.getCertificate(TEST_ALIAS_1).getPublicKey();
2034         assertNotNull(publicKey);
2035 
2036         Signature.getInstance("SHA256withECDSA").initVerify(publicKey);
2037         Signature.getInstance("NONEwithECDSA").initVerify(publicKey);
2038     }
2039 
2040     private static final int MIN_SUPPORTED_KEY_COUNT = 1500;
2041     private static final Duration LARGE_NUMBER_OF_KEYS_TEST_MAX_DURATION = Duration.ofMinutes(4);
2042     private static final Duration LARGE_NUMBER_OF_KEYS_TEST_MAX_DURATION_WATCH
2043             = Duration.ofMinutes(6);
2044 
2045     // Helper that tells callers if a given Duration has been exceeded since creation.
2046     private static class TimeBox {
2047         private long mStartTimeNanos = System.nanoTime();
2048         private Duration mMaxDuration;
2049 
TimeBox(Duration maxDuration)2050         public TimeBox(Duration maxDuration) { mMaxDuration = maxDuration; }
2051 
isOutOfTime()2052         public boolean isOutOfTime() {
2053             long nowNanos = System.nanoTime();
2054             if (nowNanos < mStartTimeNanos) {
2055                 return true;
2056             }
2057             return nowNanos - mStartTimeNanos > mMaxDuration.toNanos();
2058         }
2059 
elapsed()2060         public Duration elapsed() {
2061             return Duration.ofNanos(System.nanoTime() - mStartTimeNanos);
2062         }
2063     }
2064 
2065     @LargeTest
testKeyStore_LargeNumberOfKeysSupported_RSA()2066     public void testKeyStore_LargeNumberOfKeysSupported_RSA() throws Exception {
2067         // This test imports key1, then lots of other keys, then key2, and then confirms that
2068         // key1 and key2 backed by Android Keystore work fine. The assumption is that if the
2069         // underlying implementation has a limit on the number of keys, it'll either delete the
2070         // oldest key (key1), or will refuse to add keys (key2).
2071         // The test imports up MAX_NUMBER_OF_KEYS in a fixed amount of time, balancing the desire
2072         // to load many keys while also limiting maximum test time. This allows fast hardware to
2073         // run the test more quickly while also ensuring slower hardware loads as many keys as
2074         // possible within mMaxImportDuration.
2075 
2076         Certificate cert1 = TestUtils.getRawResX509Certificate(getContext(), R.raw.rsa_key1_cert);
2077         PrivateKey privateKey1 = TestUtils.getRawResPrivateKey(getContext(), R.raw.rsa_key1_pkcs8);
2078         String entryName1 = "test0";
2079 
2080         Certificate cert2 = TestUtils.getRawResX509Certificate(getContext(), R.raw.rsa_key2_cert);
2081         PrivateKey privateKey2 = TestUtils.getRawResPrivateKey(getContext(), R.raw.rsa_key2_pkcs8);
2082 
2083         Certificate cert3 = generateCertificate(FAKE_RSA_USER_1);
2084         PrivateKey privateKey3 = generatePrivateKey("RSA", FAKE_RSA_KEY_1);
2085 
2086         final int MAX_NUMBER_OF_KEYS = 2500;
2087         final String ALIAS_PREFIX = "test_large_number_of_rsa_keys_";
2088         int keyCount = 0;
2089 
2090         mKeyStore.load(null);
2091         try {
2092             KeyProtection protectionParams = new KeyProtection.Builder(
2093                     KeyProperties.PURPOSE_SIGN)
2094                     .setDigests(KeyProperties.DIGEST_SHA256)
2095                     .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
2096                     .build();
2097             mKeyStore.setEntry(entryName1,
2098                     new KeyStore.PrivateKeyEntry(privateKey1, new Certificate[] {cert1}),
2099                     protectionParams);
2100 
2101             keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX,
2102                     new PrivateKeyEntry(privateKey3, new Certificate[] {cert3}), protectionParams);
2103 
2104             keyCount++;
2105             String entryName2 = "test" + keyCount;
2106             mKeyStore.setEntry(entryName2,
2107                     new KeyStore.PrivateKeyEntry(privateKey2, new Certificate[] {cert2}),
2108                     protectionParams);
2109             PrivateKey keystorePrivateKey2 = (PrivateKey) mKeyStore.getKey(entryName2, null);
2110             PrivateKey keystorePrivateKey1 = (PrivateKey) mKeyStore.getKey(entryName1, null);
2111 
2112             byte[] message = "This is a test".getBytes("UTF-8");
2113 
2114             Signature sig = Signature.getInstance("SHA256withRSA");
2115             sig.initSign(keystorePrivateKey1);
2116             sig.update(message);
2117             byte[] signature = sig.sign();
2118             sig = Signature.getInstance(sig.getAlgorithm());
2119             sig.initVerify(cert1.getPublicKey());
2120             sig.update(message);
2121             assertTrue(sig.verify(signature));
2122 
2123             sig = Signature.getInstance(sig.getAlgorithm());
2124             sig.initSign(keystorePrivateKey2);
2125             sig.update(message);
2126             signature = sig.sign();
2127             sig = Signature.getInstance(sig.getAlgorithm());
2128             sig.initVerify(cert2.getPublicKey());
2129             sig.update(message);
2130             assertTrue(sig.verify(signature));
2131         } finally {
2132             deleteManyTestKeys(keyCount, ALIAS_PREFIX);
2133         }
2134     }
2135 
2136     @LargeTest
testKeyStore_LargeNumberOfKeysSupported_EC()2137     public void testKeyStore_LargeNumberOfKeysSupported_EC() throws Exception {
2138         // This test imports key1, then lots of other keys, then key2, and then confirms that
2139         // key1 and key2 backed by Android Keystore work fine. The assumption is that if the
2140         // underlying implementation has a limit on the number of keys, it'll either delete the
2141         // oldest key (key1), or will refuse to add keys (key2).
2142         // The test imports as many keys as it can in a fixed amount of time instead of stopping
2143         // at MIN_SUPPORTED_KEY_COUNT to balance the desire to support an unlimited number of keys
2144         // with the constraints on how long the test can run and performance differences of hardware
2145         // under test.
2146 
2147         TimeBox timeBox = new TimeBox(mMaxImportDuration);
2148 
2149         Certificate cert1 = TestUtils.getRawResX509Certificate(getContext(), R.raw.ec_key1_cert);
2150         PrivateKey privateKey1 = TestUtils.getRawResPrivateKey(getContext(), R.raw.ec_key1_pkcs8);
2151         String entryName1 = "test0";
2152 
2153         Certificate cert2 = TestUtils.getRawResX509Certificate(getContext(), R.raw.ec_key2_cert);
2154         PrivateKey privateKey2 = TestUtils.getRawResPrivateKey(getContext(), R.raw.ec_key2_pkcs8);
2155 
2156         Certificate cert3 = generateCertificate(FAKE_EC_USER_1);
2157         PrivateKey privateKey3 = generatePrivateKey("EC", FAKE_EC_KEY_1);
2158 
2159         final int MAX_NUMBER_OF_KEYS = 2500;
2160         final String ALIAS_PREFIX = "test_large_number_of_ec_keys_";
2161         int keyCount = 0;
2162 
2163         mKeyStore.load(null);
2164         try {
2165             KeyProtection protectionParams = new KeyProtection.Builder(
2166                     KeyProperties.PURPOSE_SIGN)
2167                     .setDigests(KeyProperties.DIGEST_SHA256)
2168                     .build();
2169             mKeyStore.setEntry(entryName1,
2170                     new KeyStore.PrivateKeyEntry(privateKey1, new Certificate[] {cert1}),
2171                     protectionParams);
2172 
2173             keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX,
2174                     new KeyStore.PrivateKeyEntry(privateKey3, new Certificate[] {cert3}),
2175                     protectionParams);
2176 
2177             keyCount++;
2178             String entryName2 = "test" + keyCount;
2179             mKeyStore.setEntry(entryName2,
2180                     new KeyStore.PrivateKeyEntry(privateKey2, new Certificate[] {cert2}),
2181                     protectionParams);
2182             PrivateKey keystorePrivateKey2 = (PrivateKey) mKeyStore.getKey(entryName2, null);
2183             PrivateKey keystorePrivateKey1 = (PrivateKey) mKeyStore.getKey(entryName1, null);
2184 
2185             byte[] message = "This is a test".getBytes("UTF-8");
2186 
2187             Signature sig = Signature.getInstance("SHA256withECDSA");
2188             sig.initSign(keystorePrivateKey1);
2189             sig.update(message);
2190             byte[] signature = sig.sign();
2191             sig = Signature.getInstance(sig.getAlgorithm());
2192             sig.initVerify(cert1.getPublicKey());
2193             sig.update(message);
2194             assertTrue(sig.verify(signature));
2195 
2196             sig = Signature.getInstance(sig.getAlgorithm());
2197             sig.initSign(keystorePrivateKey2);
2198             sig.update(message);
2199             signature = sig.sign();
2200             sig = Signature.getInstance(sig.getAlgorithm());
2201             sig.initVerify(cert2.getPublicKey());
2202             sig.update(message);
2203             assertTrue(sig.verify(signature));
2204         } finally {
2205             deleteManyTestKeys(keyCount, ALIAS_PREFIX);
2206         }
2207     }
2208 
2209     @LargeTest
testKeyStore_LargeNumberOfKeysSupported_AES()2210     public void testKeyStore_LargeNumberOfKeysSupported_AES() throws Exception {
2211         // This test imports key1, then lots of other keys, then key2, and then confirms that
2212         // key1 and key2 backed by Android Keystore work fine. The assumption is that if the
2213         // underlying implementation has a limit on the number of keys, it'll either delete the
2214         // oldest key (key1), or will refuse to add keys (key2).
2215         // The test imports up MAX_NUMBER_OF_KEYS in a fixed amount of time, balancing the desire
2216         // to load many keys while also limiting maximum test time. This allows fast hardware to
2217         // run the test more quickly while also ensuring slower hardware loads as many keys as
2218         // possible within mMaxImportDuration.
2219 
2220         SecretKey key1 = new TransparentSecretKey(
2221                 HexEncoding.decode("010203040506070809fafbfcfdfeffcc"), "AES");
2222         String entryName1 = "test0";
2223 
2224         SecretKey key2 = new TransparentSecretKey(
2225                 HexEncoding.decode("808182838485868788897a7b7c7d7e7f"), "AES");
2226 
2227         SecretKey key3 = new TransparentSecretKey(
2228                 HexEncoding.decode("33333333333333333333777777777777"), "AES");
2229 
2230         final int MAX_NUMBER_OF_KEYS = 10000;
2231         final String ALIAS_PREFIX = "test_large_number_of_aes_keys_";
2232         int keyCount = 0;
2233 
2234         mKeyStore.load(null);
2235         try {
2236             KeyProtection protectionParams = new KeyProtection.Builder(
2237                     KeyProperties.PURPOSE_ENCRYPT)
2238                     .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
2239                     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
2240                     .build();
2241             mKeyStore.setEntry(entryName1, new KeyStore.SecretKeyEntry(key1), protectionParams);
2242 
2243             keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX,
2244                     new KeyStore.SecretKeyEntry(key3), protectionParams);
2245 
2246             ++keyCount;
2247             String entryName2 = "test" + keyCount;
2248             mKeyStore.setEntry(entryName2, new KeyStore.SecretKeyEntry(key2), protectionParams);
2249             SecretKey keystoreKey2 = (SecretKey) mKeyStore.getKey(entryName2, null);
2250             SecretKey keystoreKey1 = (SecretKey) mKeyStore.getKey(entryName1, null);
2251 
2252             byte[] plaintext = "This is a test".getBytes("UTF-8");
2253             Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
2254             cipher.init(Cipher.ENCRYPT_MODE, keystoreKey1);
2255             byte[] ciphertext = cipher.doFinal(plaintext);
2256             AlgorithmParameters cipherParams = cipher.getParameters();
2257             cipher = Cipher.getInstance(cipher.getAlgorithm());
2258             cipher.init(Cipher.DECRYPT_MODE, key1, cipherParams);
2259             MoreAsserts.assertEquals(plaintext, cipher.doFinal(ciphertext));
2260 
2261             cipher = Cipher.getInstance(cipher.getAlgorithm());
2262             cipher.init(Cipher.ENCRYPT_MODE, keystoreKey2);
2263             ciphertext = cipher.doFinal(plaintext);
2264             cipherParams = cipher.getParameters();
2265             cipher = Cipher.getInstance(cipher.getAlgorithm());
2266             cipher.init(Cipher.DECRYPT_MODE, key2, cipherParams);
2267             MoreAsserts.assertEquals(plaintext, cipher.doFinal(ciphertext));
2268         } finally {
2269             deleteManyTestKeys(keyCount, ALIAS_PREFIX);
2270         }
2271     }
2272 
2273     @LargeTest
testKeyStore_LargeNumberOfKeysSupported_HMAC()2274     public void testKeyStore_LargeNumberOfKeysSupported_HMAC() throws Exception {
2275         // This test imports key1, then lots of other keys, then key2, and then confirms that
2276         // key1 and key2 backed by Android Keystore work fine. The assumption is that if the
2277         // underlying implementation has a limit on the number of keys, it'll either delete the
2278         // oldest key (key1), or will refuse to add keys (key2).
2279         // The test imports as many keys as it can in a fixed amount of time instead of stopping
2280         // at MIN_SUPPORTED_KEY_COUNT to balance the desire to support an unlimited number of keys
2281         // with the constraints on how long the test can run and performance differences of hardware
2282         // under test.
2283 
2284         TimeBox timeBox = new TimeBox(mMaxImportDuration);
2285 
2286         SecretKey key1 = new TransparentSecretKey(
2287                 HexEncoding.decode("010203040506070809fafbfcfdfeffcc"), "HmacSHA256");
2288         String entryName1 = "test0";
2289 
2290         SecretKey key2 = new TransparentSecretKey(
2291                 HexEncoding.decode("808182838485868788897a7b7c7d7e7f"), "HmacSHA256");
2292 
2293         SecretKey key3 = new TransparentSecretKey(
2294                 HexEncoding.decode("33333333333333333333777777777777"), "HmacSHA256");
2295 
2296         final int MAX_NUMBER_OF_KEYS = 10000;
2297         final String ALIAS_PREFIX = "test_large_number_of_hmac_keys_";
2298         int keyCount = 0;
2299 
2300         mKeyStore.load(null);
2301         try {
2302             KeyProtection protectionParams = new KeyProtection.Builder(
2303                     KeyProperties.PURPOSE_SIGN)
2304                     .build();
2305             mKeyStore.setEntry(entryName1, new KeyStore.SecretKeyEntry(key1), protectionParams);
2306 
2307             keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX,
2308                             new KeyStore.SecretKeyEntry(key3), protectionParams);
2309 
2310             keyCount++;
2311             String entryName2 = "test" + keyCount;
2312             mKeyStore.setEntry(entryName2, new KeyStore.SecretKeyEntry(key2), protectionParams);
2313             SecretKey keystoreKey2 = (SecretKey) mKeyStore.getKey(entryName2, null);
2314             SecretKey keystoreKey1 = (SecretKey) mKeyStore.getKey(entryName1, null);
2315 
2316             byte[] message = "This is a test".getBytes("UTF-8");
2317             Mac mac = Mac.getInstance(key1.getAlgorithm());
2318             mac.init(keystoreKey1);
2319             MoreAsserts.assertEquals(
2320                     HexEncoding.decode(
2321                             "905e36f5a175f4ca54ad56b860b46f6502f883a90628dca2d33a953fb7224eaf"),
2322                     mac.doFinal(message));
2323 
2324             mac = Mac.getInstance(key2.getAlgorithm());
2325             mac.init(keystoreKey2);
2326             MoreAsserts.assertEquals(
2327                     HexEncoding.decode(
2328                             "59b57e77e4e2cb36b5c7b84af198ac004327bc549de6931a1b5505372dd8c957"),
2329                     mac.doFinal(message));
2330         } finally {
2331             deleteManyTestKeys(keyCount, ALIAS_PREFIX);
2332         }
2333     }
2334 
testKeyStore_OnlyOneDigestCanBeAuthorized_HMAC()2335     public void testKeyStore_OnlyOneDigestCanBeAuthorized_HMAC() throws Exception {
2336         mKeyStore.load(null);
2337 
2338         for (String algorithm : KeyGeneratorTest.EXPECTED_ALGORITHMS) {
2339             if (!TestUtils.isHmacAlgorithm(algorithm)) {
2340                 continue;
2341             }
2342             try {
2343                 String digest = TestUtils.getHmacAlgorithmDigest(algorithm);
2344                 assertNotNull(digest);
2345                 SecretKey keyBeingImported = new TransparentSecretKey(new byte[16], algorithm);
2346 
2347                 KeyProtection.Builder goodSpec =
2348                         new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN);
2349 
2350                 // Digests authorization not specified in import parameters
2351                 assertFalse(goodSpec.build().isDigestsSpecified());
2352                 mKeyStore.setEntry(TEST_ALIAS_1,
2353                         new KeyStore.SecretKeyEntry(keyBeingImported),
2354                         goodSpec.build());
2355                 SecretKey key = (SecretKey) mKeyStore.getKey(TEST_ALIAS_1, null);
2356                 TestUtils.assertContentsInAnyOrder(
2357                         Arrays.asList(TestUtils.getKeyInfo(key).getDigests()), digest);
2358 
2359                 // The same digest is specified in import parameters
2360                 mKeyStore.setEntry(TEST_ALIAS_1,
2361                         new KeyStore.SecretKeyEntry(keyBeingImported),
2362                         TestUtils.buildUpon(goodSpec).setDigests(digest).build());
2363                 key = (SecretKey) mKeyStore.getKey(TEST_ALIAS_1, null);
2364                 TestUtils.assertContentsInAnyOrder(
2365                         Arrays.asList(TestUtils.getKeyInfo(key).getDigests()), digest);
2366 
2367                 // Empty set of digests specified in import parameters
2368                 try {
2369                     mKeyStore.setEntry(TEST_ALIAS_1,
2370                             new KeyStore.SecretKeyEntry(keyBeingImported),
2371                             TestUtils.buildUpon(goodSpec).setDigests().build());
2372                     fail();
2373                 } catch (KeyStoreException expected) {}
2374 
2375                 // A different digest specified in import parameters
2376                 String anotherDigest = "SHA-256".equalsIgnoreCase(digest) ? "SHA-384" : "SHA-256";
2377                 try {
2378                     mKeyStore.setEntry(TEST_ALIAS_1,
2379                             new KeyStore.SecretKeyEntry(keyBeingImported),
2380                             TestUtils.buildUpon(goodSpec).setDigests(anotherDigest).build());
2381                     fail();
2382                 } catch (KeyStoreException expected) {}
2383                 try {
2384                     mKeyStore.setEntry(TEST_ALIAS_1,
2385                             new KeyStore.SecretKeyEntry(keyBeingImported),
2386                             TestUtils.buildUpon(goodSpec)
2387                                     .setDigests(digest, anotherDigest)
2388                                     .build());
2389                     fail();
2390                 } catch (KeyStoreException expected) {}
2391             } catch (Throwable e) {
2392                 throw new RuntimeException("Failed for " + algorithm, e);
2393             }
2394         }
2395     }
2396 
testKeyStore_ImportSupportedSizes_AES()2397     public void testKeyStore_ImportSupportedSizes_AES() throws Exception {
2398         mKeyStore.load(null);
2399 
2400         KeyProtection params = new KeyProtection.Builder(
2401                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
2402                 .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
2403                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
2404                 .build();
2405         String alias = "test1";
2406         mKeyStore.deleteEntry(alias);
2407         assertFalse(mKeyStore.containsAlias(alias));
2408         for (int keySizeBytes = 0; keySizeBytes <= 512 / 8; keySizeBytes++) {
2409             int keySizeBits = keySizeBytes * 8;
2410             try {
2411                 KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(
2412                         new TransparentSecretKey(new byte[keySizeBytes], "AES"));
2413                 if (TestUtils.contains(KeyGeneratorTest.AES_SUPPORTED_KEY_SIZES, keySizeBits)) {
2414                     mKeyStore.setEntry(alias, entry, params);
2415                     SecretKey key = (SecretKey) mKeyStore.getKey(alias, null);
2416                     assertEquals("AES", key.getAlgorithm());
2417                     assertEquals(keySizeBits, TestUtils.getKeyInfo(key).getKeySize());
2418                 } else {
2419                     mKeyStore.deleteEntry(alias);
2420                     assertFalse(mKeyStore.containsAlias(alias));
2421                     try {
2422                         mKeyStore.setEntry(alias, entry, params);
2423                         fail();
2424                     } catch (KeyStoreException expected) {}
2425                     assertFalse(mKeyStore.containsAlias(alias));
2426                 }
2427             } catch (Throwable e) {
2428                 throw new RuntimeException("Failed for key size " + keySizeBits, e);
2429             }
2430         }
2431     }
2432 
testKeyStore_ImportSupportedSizes_HMAC()2433     public void testKeyStore_ImportSupportedSizes_HMAC() throws Exception {
2434         mKeyStore.load(null);
2435 
2436         KeyProtection params = new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build();
2437         String alias = "test1";
2438         mKeyStore.deleteEntry(alias);
2439         assertFalse(mKeyStore.containsAlias(alias));
2440         for (String algorithm : KeyGeneratorTest.EXPECTED_ALGORITHMS) {
2441             if (!TestUtils.isHmacAlgorithm(algorithm)) {
2442                 continue;
2443             }
2444             for (int keySizeBytes = 8; keySizeBytes <= 1024 / 8; keySizeBytes++) {
2445                 try {
2446                     KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(
2447                             new TransparentSecretKey(new byte[keySizeBytes], algorithm));
2448                     if (keySizeBytes > 0) {
2449                         mKeyStore.setEntry(alias, entry, params);
2450                         SecretKey key = (SecretKey) mKeyStore.getKey(alias, null);
2451                         assertEquals(algorithm, key.getAlgorithm());
2452                         assertEquals(keySizeBytes * 8, TestUtils.getKeyInfo(key).getKeySize());
2453                     } else {
2454                         mKeyStore.deleteEntry(alias);
2455                         assertFalse(mKeyStore.containsAlias(alias));
2456                         try {
2457                             mKeyStore.setEntry(alias, entry, params);
2458                             fail();
2459                         } catch (KeyStoreException expected) {}
2460                     }
2461                 } catch (Throwable e) {
2462                     throw new RuntimeException(
2463                             "Failed for " + algorithm + " with key size " + (keySizeBytes * 8), e);
2464                 }
2465             }
2466         }
2467     }
2468 
testKeyStore_ImportSupportedSizes_EC()2469     public void testKeyStore_ImportSupportedSizes_EC() throws Exception {
2470         mKeyStore.load(null);
2471         KeyProtection params =
2472                 TestUtils.getMinimalWorkingImportParametersForSigningingWith("SHA256withECDSA");
2473         checkKeyPairImportSucceeds(
2474                 "secp224r1", R.raw.ec_key3_secp224r1_pkcs8, R.raw.ec_key3_secp224r1_cert, params);
2475         checkKeyPairImportSucceeds(
2476                 "secp256r1", R.raw.ec_key4_secp256r1_pkcs8, R.raw.ec_key4_secp256r1_cert, params);
2477         checkKeyPairImportSucceeds(
2478                 "secp384r1", R.raw.ec_key5_secp384r1_pkcs8, R.raw.ec_key5_secp384r1_cert, params);
2479         checkKeyPairImportSucceeds(
2480                 "secp512r1", R.raw.ec_key6_secp521r1_pkcs8, R.raw.ec_key6_secp521r1_cert, params);
2481     }
2482 
testKeyStore_ImportSupportedSizes_RSA()2483     public void testKeyStore_ImportSupportedSizes_RSA() throws Exception {
2484         mKeyStore.load(null);
2485         KeyProtection params =
2486                 TestUtils.getMinimalWorkingImportParametersForSigningingWith("SHA256withRSA");
2487         checkKeyPairImportSucceeds(
2488                 "512", R.raw.rsa_key5_512_pkcs8, R.raw.rsa_key5_512_cert, params);
2489         checkKeyPairImportSucceeds(
2490                 "768", R.raw.rsa_key6_768_pkcs8, R.raw.rsa_key6_768_cert, params);
2491         checkKeyPairImportSucceeds(
2492                 "1024", R.raw.rsa_key3_1024_pkcs8, R.raw.rsa_key3_1024_cert, params);
2493         checkKeyPairImportSucceeds(
2494                 "2048", R.raw.rsa_key8_2048_pkcs8, R.raw.rsa_key8_2048_cert, params);
2495         checkKeyPairImportSucceeds(
2496                 "3072", R.raw.rsa_key7_3072_pksc8, R.raw.rsa_key7_3072_cert, params);
2497         checkKeyPairImportSucceeds(
2498                 "4096", R.raw.rsa_key4_4096_pkcs8, R.raw.rsa_key4_4096_cert, params);
2499     }
2500 
checkKeyPairImportSucceeds( String alias, int privateResId, int certResId, KeyProtection params)2501     private void checkKeyPairImportSucceeds(
2502             String alias, int privateResId, int certResId, KeyProtection params) throws Exception {
2503         try {
2504             mKeyStore.deleteEntry(alias);
2505             TestUtils.importIntoAndroidKeyStore(
2506                     alias, getContext(), privateResId, certResId, params);
2507         } catch (Throwable e) {
2508             throw new RuntimeException("Failed for " + alias, e);
2509         } finally {
2510             try {
2511                 mKeyStore.deleteEntry(alias);
2512             } catch (Exception ignored) {}
2513         }
2514     }
2515 
2516     /**
2517      * Import <code>key</code> up to <code>numberOfKeys</code> times, using parameters generated by
2518      * <code>paramsBuilder</code>. This operation is done with multiple threads (one per logical
2519      * CPU) to both stress keystore as well as improve throughput. Each key alias is prefixed with
2520      * <code>aliasPrefix</code>.
2521      *
2522      * This method is time-bounded
2523      */
importKeyManyTimes(int numberOfKeys, String aliasPrefix, Entry keyEntry, KeyProtection protectionParams)2524     private int importKeyManyTimes(int numberOfKeys, String aliasPrefix, Entry keyEntry,
2525             KeyProtection protectionParams)
2526             throws InterruptedException {
2527         TimeBox timeBox = new TimeBox(mMaxImportDuration);
2528         AtomicInteger keyCounter = new AtomicInteger(0);
2529         ArrayList<Thread> threads = new ArrayList<>();
2530         for (int i = 0; i < Runtime.getRuntime().availableProcessors(); ++i) {
2531             threads.add(new Thread(() -> {
2532                 // Import key lots of times, under different aliases. Do this until we either run
2533                 // out of time or we import the key numberOfKeys times.
2534                 while (!timeBox.isOutOfTime()) {
2535                     int count = keyCounter.incrementAndGet();
2536                     if (count > numberOfKeys) {
2537                         // The loop is inherently racy, as multiple threads are simultaneously
2538                         // performing incrementAndGet operations. We only know if we've hit the
2539                         // limit _after_ we already incremented the counter. "Give the count back"
2540                         // before breaking so that we ensure keyCounter is accurate.
2541                         keyCounter.decrementAndGet();
2542                         break;
2543                     }
2544                     if ((count % 1000) == 0) {
2545                         Log.i(TAG, "Imported " + count + " keys");
2546                     }
2547                     String entryAlias = aliasPrefix + count;
2548                     try {
2549                         mKeyStore.setEntry(entryAlias, keyEntry, protectionParams);
2550                     } catch (Throwable e) {
2551                         throw new RuntimeException("Entry " + entryAlias + " import failed", e);
2552                     }
2553                 }
2554             }));
2555         }
2556         // Start all the threads as close to one another as possible to spread the load evenly
2557         for (int i = 0; i < threads.size(); ++i) {
2558             threads.get(i).start();
2559         }
2560         for (int i = 0; i < threads.size(); ++i) {
2561             threads.get(i).join();
2562         }
2563         Log.i(TAG, "Imported " + keyCounter.get() + " keys in " + timeBox.elapsed());
2564         if (keyCounter.get() < MIN_SUPPORTED_KEY_COUNT) {
2565             fail("Failed to import " + MIN_SUPPORTED_KEY_COUNT + " keys in "
2566                     + timeBox.elapsed() + ". Imported: " + keyCounter.get() + " keys");
2567         }
2568 
2569         return keyCounter.get();
2570     }
2571 
2572     /**
2573      * Delete <code>numberOfKeys</code> keys that follow the pattern "[aliasPrefix][keyCounter]".
2574      * This is done across multiple threads to both increase throughput as well as stress keystore.
2575      */
deleteManyTestKeys(int numberOfKeys, String aliasPrefix)2576     private void deleteManyTestKeys(int numberOfKeys, String aliasPrefix)
2577             throws InterruptedException {
2578         // Clean up Keystore without using KeyStore.aliases() which can't handle this many
2579         // entries.
2580         AtomicInteger keyCounter = new AtomicInteger(numberOfKeys);
2581         Log.i(TAG, "Deleting imported keys");
2582         ArrayList<Thread> threads = new ArrayList<>();
2583         for (int i = 0; i < Runtime.getRuntime().availableProcessors(); ++i) {
2584             Log.i(TAG, "Spinning up cleanup thread " + i);
2585             threads.add(new Thread(() -> {
2586                 for (int key = keyCounter.getAndDecrement(); key > 0;
2587                         key = keyCounter.getAndDecrement()) {
2588                     if ((key > 0) && ((key % 1000) == 0)) {
2589                         Log.i(TAG, "Deleted " + key + " keys");
2590                     }
2591                     try {
2592                         mKeyStore.deleteEntry("test" + key);
2593                     } catch (Exception e) {
2594                         fail("Unexpected exception in key cleanup: " + e);
2595                     }
2596                 }
2597             }));
2598         }
2599         for (int i = 0; i < threads.size(); ++i) {
2600             threads.get(i).start();
2601         }
2602         for (int i = 0; i < threads.size(); ++i) {
2603             Log.i(TAG, "Joining test thread " + i);
2604             threads.get(i).join();
2605         }
2606         Log.i(TAG, "Deleted " + numberOfKeys + " keys");
2607     }
2608 }
2609