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