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