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