1 /*
2  * Copyright (C) 2009 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.webkit.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotEquals;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25 
26 import android.annotation.CallSuper;
27 import android.net.http.SslCertificate;
28 import android.net.http.SslError;
29 import android.os.StrictMode;
30 import android.os.StrictMode.ThreadPolicy;
31 import android.platform.test.annotations.AppModeFull;
32 import android.util.Log;
33 import android.webkit.ClientCertRequest;
34 import android.webkit.SslErrorHandler;
35 import android.webkit.WebView;
36 import android.webkit.WebViewClient;
37 import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
38 
39 import androidx.test.ext.junit.rules.ActivityScenarioRule;
40 import androidx.test.ext.junit.runners.AndroidJUnit4;
41 import androidx.test.filters.MediumTest;
42 
43 import com.android.compatibility.common.util.NullWebViewUtils;
44 import com.android.compatibility.common.util.PollingCheck;
45 
46 import org.junit.After;
47 import org.junit.Assume;
48 import org.junit.Before;
49 import org.junit.Rule;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 
53 import java.io.ByteArrayInputStream;
54 import java.io.File;
55 import java.security.KeyFactory;
56 import java.security.KeyStore;
57 import java.security.Principal;
58 import java.security.PrivateKey;
59 import java.security.cert.CertificateFactory;
60 import java.security.cert.X509Certificate;
61 import java.security.spec.PKCS8EncodedKeySpec;
62 import java.util.concurrent.atomic.AtomicBoolean;
63 
64 @AppModeFull(reason = "Instant apps cannot bind sockets")
65 @MediumTest
66 @RunWith(AndroidJUnit4.class)
67 public class WebViewSslTest extends SharedWebViewTest {
68     private static final String LOGTAG = "WebViewSslTest";
69 
70     /**
71      * Taken verbatim from AndroidKeyStoreTest.java. Copying the build notes here for reference.
72      * The keys and certificates below are generated with:
73      *
74      * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
75      * openssl req -newkey rsa:1024 -keyout userkey.pem -nodes -days 3650 -out userkey.req
76      * mkdir -p demoCA/newcerts
77      * touch demoCA/index.txt
78      * echo "01" > demoCA/serial
79      * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
80      */
81 
82     /**
83      * Generated from above and converted with:
84      *
85      * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
86      */
87     private static final byte[] FAKE_RSA_USER_1 = new byte[] {
88             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x95, (byte) 0x30, (byte) 0x82,
89             (byte) 0x01, (byte) 0xfe, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
90             (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
91             (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
92             (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
93             (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
94             (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
95             (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
96             (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
97             (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
98             (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
99             (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
100             (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
101             (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
102             (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
103             (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
104             (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
105             (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
106             (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30, (byte) 0x1e,
107             (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32, (byte) 0x30, (byte) 0x38,
108             (byte) 0x31, (byte) 0x34, (byte) 0x32, (byte) 0x33, (byte) 0x32, (byte) 0x35,
109             (byte) 0x34, (byte) 0x38, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32,
110             (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x32,
111             (byte) 0x33, (byte) 0x32, (byte) 0x35, (byte) 0x34, (byte) 0x38, (byte) 0x5a,
112             (byte) 0x30, (byte) 0x55, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
113             (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13,
114             (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
115             (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08,
116             (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31, (byte) 0x1b,
117             (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
118             (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e, (byte) 0x64,
119             (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x54,
120             (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43, (byte) 0x61,
121             (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x31, (byte) 0x1c, (byte) 0x30,
122             (byte) 0x1a, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03,
123             (byte) 0x13, (byte) 0x13, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76,
124             (byte) 0x65, (byte) 0x72, (byte) 0x31, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
125             (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
126             (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x81, (byte) 0x9f,
127             (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
128             (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
129             (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8d,
130             (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81,
131             (byte) 0x81, (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6,
132             (byte) 0x5b, (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c,
133             (byte) 0x66, (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86,
134             (byte) 0x8a, (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3,
135             (byte) 0x02, (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08,
136             (byte) 0xf3, (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04,
137             (byte) 0x6d, (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f,
138             (byte) 0x67, (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c,
139             (byte) 0xcb, (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30,
140             (byte) 0xe2, (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5,
141             (byte) 0x79, (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b,
142             (byte) 0xce, (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb,
143             (byte) 0x08, (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff,
144             (byte) 0x3b, (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9,
145             (byte) 0xc4, (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29,
146             (byte) 0x0d, (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b,
147             (byte) 0x23, (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78,
148             (byte) 0x08, (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5,
149             (byte) 0xf1, (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19,
150             (byte) 0xb4, (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03,
151             (byte) 0x16, (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce,
152             (byte) 0x9e, (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03,
153             (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x7b, (byte) 0x30,
154             (byte) 0x79, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
155             (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00,
156             (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86,
157             (byte) 0x48, (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01,
158             (byte) 0x0d, (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f,
159             (byte) 0x70, (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c,
160             (byte) 0x20, (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72,
161             (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43,
162             (byte) 0x65, (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69,
163             (byte) 0x63, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d,
164             (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04,
165             (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x32, (byte) 0xa1, (byte) 0x1e,
166             (byte) 0x6b, (byte) 0x69, (byte) 0x04, (byte) 0xfe, (byte) 0xb3, (byte) 0xcd,
167             (byte) 0xf8, (byte) 0xbb, (byte) 0x14, (byte) 0xcd, (byte) 0xff, (byte) 0xd4,
168             (byte) 0x16, (byte) 0xc3, (byte) 0xab, (byte) 0x44, (byte) 0x2f, (byte) 0x30,
169             (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23,
170             (byte) 0x04, (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14,
171             (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60,
172             (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c,
173             (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e,
174             (byte) 0x5d, (byte) 0x51, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
175             (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
176             (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03,
177             (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x46, (byte) 0x42, (byte) 0xef,
178             (byte) 0x56, (byte) 0x89, (byte) 0x78, (byte) 0x90, (byte) 0x38, (byte) 0x24,
179             (byte) 0x9f, (byte) 0x8c, (byte) 0x7a, (byte) 0xce, (byte) 0x7a, (byte) 0xa5,
180             (byte) 0xb5, (byte) 0x1e, (byte) 0x74, (byte) 0x96, (byte) 0x34, (byte) 0x49,
181             (byte) 0x8b, (byte) 0xed, (byte) 0x44, (byte) 0xb3, (byte) 0xc9, (byte) 0x05,
182             (byte) 0xd7, (byte) 0x48, (byte) 0x55, (byte) 0x52, (byte) 0x59, (byte) 0x15,
183             (byte) 0x0b, (byte) 0xaa, (byte) 0x16, (byte) 0x86, (byte) 0xd2, (byte) 0x8e,
184             (byte) 0x16, (byte) 0x99, (byte) 0xe8, (byte) 0x5f, (byte) 0x11, (byte) 0x71,
185             (byte) 0x42, (byte) 0x55, (byte) 0xd1, (byte) 0xc4, (byte) 0x6f, (byte) 0x2e,
186             (byte) 0xa9, (byte) 0x64, (byte) 0x6f, (byte) 0xd8, (byte) 0xfd, (byte) 0x43,
187             (byte) 0x13, (byte) 0x24, (byte) 0xaa, (byte) 0x67, (byte) 0xe6, (byte) 0xf5,
188             (byte) 0xca, (byte) 0x80, (byte) 0x5e, (byte) 0x3a, (byte) 0x3e, (byte) 0xcc,
189             (byte) 0x4f, (byte) 0xba, (byte) 0x87, (byte) 0xe6, (byte) 0xae, (byte) 0xbf,
190             (byte) 0x8f, (byte) 0xd5, (byte) 0x28, (byte) 0x38, (byte) 0x58, (byte) 0x30,
191             (byte) 0x24, (byte) 0xf6, (byte) 0x53, (byte) 0x5b, (byte) 0x41, (byte) 0x53,
192             (byte) 0xe6, (byte) 0x45, (byte) 0xbc, (byte) 0xbe, (byte) 0xe6, (byte) 0xbb,
193             (byte) 0x5d, (byte) 0xd8, (byte) 0xa7, (byte) 0xf9, (byte) 0x64, (byte) 0x99,
194             (byte) 0x04, (byte) 0x43, (byte) 0x75, (byte) 0xd7, (byte) 0x2d, (byte) 0x32,
195             (byte) 0x0a, (byte) 0x94, (byte) 0xaf, (byte) 0x06, (byte) 0x34, (byte) 0xae,
196             (byte) 0x46, (byte) 0xbd, (byte) 0xda, (byte) 0x00, (byte) 0x0e, (byte) 0x25,
197             (byte) 0xc2, (byte) 0xf7, (byte) 0xc9, (byte) 0xc3, (byte) 0x65, (byte) 0xd2,
198             (byte) 0x08, (byte) 0x41, (byte) 0x0a, (byte) 0xf3, (byte) 0x72
199     };
200 
201     /**
202      * Generated from above and converted with:
203      *
204      * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
205      */
206     private static final byte[] FAKE_RSA_CA_1 = {
207             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xce, (byte) 0x30, (byte) 0x82,
208             (byte) 0x02, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
209             (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0x6a,
210             (byte) 0xa2, (byte) 0xf4, (byte) 0x2e, (byte) 0x55, (byte) 0x48, (byte) 0x0a,
211             (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
212             (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
213             (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31,
214             (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
215             (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53,
216             (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
217             (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43,
218             (byte) 0x41, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06,
219             (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d,
220             (byte) 0x4d, (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61,
221             (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65,
222             (byte) 0x77, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
223             (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12,
224             (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69,
225             (byte) 0x64, (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74,
226             (byte) 0x20, (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73,
227             (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32,
228             (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x34, (byte) 0x31, (byte) 0x36,
229             (byte) 0x35, (byte) 0x35, (byte) 0x34, (byte) 0x34, (byte) 0x5a, (byte) 0x17,
230             (byte) 0x0d, (byte) 0x32, (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31,
231             (byte) 0x32, (byte) 0x31, (byte) 0x36, (byte) 0x35, (byte) 0x35, (byte) 0x34,
232             (byte) 0x34, (byte) 0x5a, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b,
233             (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
234             (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31,
235             (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
236             (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41,
237             (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03,
238             (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d,
239             (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69,
240             (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77,
241             (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
242             (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41,
243             (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64,
244             (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20,
245             (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30,
246             (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
247             (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
248             (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
249             (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
250             (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa3, (byte) 0x72,
251             (byte) 0xab, (byte) 0xd0, (byte) 0xe4, (byte) 0xad, (byte) 0x2f, (byte) 0xe7,
252             (byte) 0xe2, (byte) 0x79, (byte) 0x07, (byte) 0x36, (byte) 0x3d, (byte) 0x0c,
253             (byte) 0x8d, (byte) 0x42, (byte) 0x9a, (byte) 0x0a, (byte) 0x33, (byte) 0x64,
254             (byte) 0xb3, (byte) 0xcd, (byte) 0xb2, (byte) 0xd7, (byte) 0x3a, (byte) 0x42,
255             (byte) 0x06, (byte) 0x77, (byte) 0x45, (byte) 0x29, (byte) 0xe9, (byte) 0xcb,
256             (byte) 0xb7, (byte) 0x4a, (byte) 0xd6, (byte) 0xee, (byte) 0xad, (byte) 0x01,
257             (byte) 0x91, (byte) 0x9b, (byte) 0x0c, (byte) 0x59, (byte) 0xa1, (byte) 0x03,
258             (byte) 0xfa, (byte) 0xf0, (byte) 0x5a, (byte) 0x7c, (byte) 0x4f, (byte) 0xf7,
259             (byte) 0x8d, (byte) 0x36, (byte) 0x0f, (byte) 0x1f, (byte) 0x45, (byte) 0x7d,
260             (byte) 0x1b, (byte) 0x31, (byte) 0xa1, (byte) 0x35, (byte) 0x0b, (byte) 0x00,
261             (byte) 0xed, (byte) 0x7a, (byte) 0xb6, (byte) 0xc8, (byte) 0x4e, (byte) 0xa9,
262             (byte) 0x86, (byte) 0x4c, (byte) 0x7b, (byte) 0x99, (byte) 0x57, (byte) 0x41,
263             (byte) 0x12, (byte) 0xef, (byte) 0x6b, (byte) 0xbc, (byte) 0x3d, (byte) 0x60,
264             (byte) 0xf2, (byte) 0x99, (byte) 0x1a, (byte) 0xcd, (byte) 0xed, (byte) 0x56,
265             (byte) 0xa4, (byte) 0xe5, (byte) 0x36, (byte) 0x9f, (byte) 0x24, (byte) 0x1f,
266             (byte) 0xdc, (byte) 0x89, (byte) 0x40, (byte) 0xc8, (byte) 0x99, (byte) 0x92,
267             (byte) 0xab, (byte) 0x4a, (byte) 0xb5, (byte) 0x61, (byte) 0x45, (byte) 0x62,
268             (byte) 0xff, (byte) 0xa3, (byte) 0x45, (byte) 0x65, (byte) 0xaf, (byte) 0xf6,
269             (byte) 0x27, (byte) 0x30, (byte) 0x51, (byte) 0x0e, (byte) 0x0e, (byte) 0xeb,
270             (byte) 0x79, (byte) 0x0c, (byte) 0xbe, (byte) 0xb3, (byte) 0x0a, (byte) 0x6f,
271             (byte) 0x29, (byte) 0x06, (byte) 0xdc, (byte) 0x2f, (byte) 0x6b, (byte) 0x51,
272             (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
273             (byte) 0x81, (byte) 0xb1, (byte) 0x30, (byte) 0x81, (byte) 0xae, (byte) 0x30,
274             (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e,
275             (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x33, (byte) 0x05,
276             (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60, (byte) 0xc7, (byte) 0xf9,
277             (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c, (byte) 0x8f, (byte) 0x6d,
278             (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e, (byte) 0x5d, (byte) 0x51,
279             (byte) 0x30, (byte) 0x7f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
280             (byte) 0x23, (byte) 0x04, (byte) 0x78, (byte) 0x30, (byte) 0x76, (byte) 0x80,
281             (byte) 0x14, (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f,
282             (byte) 0x60, (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73,
283             (byte) 0x5c, (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97,
284             (byte) 0x8e, (byte) 0x5d, (byte) 0x51, (byte) 0xa1, (byte) 0x53, (byte) 0xa4,
285             (byte) 0x51, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
286             (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
287             (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
288             (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
289             (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
290             (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
291             (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
292             (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
293             (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
294             (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
295             (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
296             (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
297             (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
298             (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x82, (byte) 0x09,
299             (byte) 0x00, (byte) 0xe1, (byte) 0x6a, (byte) 0xa2, (byte) 0xf4, (byte) 0x2e,
300             (byte) 0x55, (byte) 0x48, (byte) 0x0a, (byte) 0x30, (byte) 0x0c, (byte) 0x06,
301             (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05,
302             (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30,
303             (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
304             (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
305             (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
306             (byte) 0x8c, (byte) 0x30, (byte) 0x42, (byte) 0xfa, (byte) 0xeb, (byte) 0x1a,
307             (byte) 0x26, (byte) 0xeb, (byte) 0xda, (byte) 0x56, (byte) 0x32, (byte) 0xf2,
308             (byte) 0x9d, (byte) 0xa5, (byte) 0x24, (byte) 0xd8, (byte) 0x3a, (byte) 0xda,
309             (byte) 0x30, (byte) 0xa6, (byte) 0x8b, (byte) 0x46, (byte) 0xfe, (byte) 0xfe,
310             (byte) 0xdb, (byte) 0xf1, (byte) 0xe6, (byte) 0xe1, (byte) 0x7c, (byte) 0x1b,
311             (byte) 0xe7, (byte) 0x77, (byte) 0x00, (byte) 0xa1, (byte) 0x1c, (byte) 0x19,
312             (byte) 0x17, (byte) 0x73, (byte) 0xb0, (byte) 0xf0, (byte) 0x9d, (byte) 0xf3,
313             (byte) 0x4f, (byte) 0xb6, (byte) 0xbc, (byte) 0xc7, (byte) 0x47, (byte) 0x85,
314             (byte) 0x2a, (byte) 0x4a, (byte) 0xa1, (byte) 0xa5, (byte) 0x58, (byte) 0xf5,
315             (byte) 0xc5, (byte) 0x1a, (byte) 0x51, (byte) 0xb1, (byte) 0x04, (byte) 0x80,
316             (byte) 0xee, (byte) 0x3a, (byte) 0xec, (byte) 0x2f, (byte) 0xe1, (byte) 0xfd,
317             (byte) 0x58, (byte) 0xeb, (byte) 0xed, (byte) 0x82, (byte) 0x9e, (byte) 0x38,
318             (byte) 0xa3, (byte) 0x24, (byte) 0x75, (byte) 0xf7, (byte) 0x3e, (byte) 0xc2,
319             (byte) 0xc5, (byte) 0x27, (byte) 0xeb, (byte) 0x6f, (byte) 0x7b, (byte) 0x50,
320             (byte) 0xda, (byte) 0x43, (byte) 0xdc, (byte) 0x3b, (byte) 0x0b, (byte) 0x6f,
321             (byte) 0x78, (byte) 0x8f, (byte) 0xb0, (byte) 0x66, (byte) 0xe1, (byte) 0x12,
322             (byte) 0x87, (byte) 0x5f, (byte) 0x97, (byte) 0x7b, (byte) 0xca, (byte) 0x14,
323             (byte) 0x79, (byte) 0xf7, (byte) 0xe8, (byte) 0x6c, (byte) 0x72, (byte) 0xdb,
324             (byte) 0x91, (byte) 0x65, (byte) 0x17, (byte) 0x54, (byte) 0xe0, (byte) 0x74,
325             (byte) 0x1d, (byte) 0xac, (byte) 0x47, (byte) 0x04, (byte) 0x12, (byte) 0xe0,
326             (byte) 0xc3, (byte) 0x66, (byte) 0x19, (byte) 0x05, (byte) 0x2e, (byte) 0x7e,
327             (byte) 0xf1, (byte) 0x61
328     };
329 
330     /**
331      * Generated from above and converted with:
332      *
333      * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
334      */
335     private static final byte[] FAKE_RSA_KEY_1 = new byte[] {
336             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
337             (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
338             (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
339             (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
340             (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
341             (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
342             (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
343             (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
344             (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
345             (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
346             (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
347             (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
348             (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
349             (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
350             (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
351             (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
352             (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
353             (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
354             (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
355             (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
356             (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
357             (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
358             (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
359             (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
360             (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
361             (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
362             (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
363             (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
364             (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
365             (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
366             (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
367             (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
368             (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
369             (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
370             (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
371             (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
372             (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
373             (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
374             (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
375             (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
376             (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
377             (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
378             (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
379             (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
380             (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
381             (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
382             (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
383             (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
384             (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
385             (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
386             (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
387             (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
388             (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
389             (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
390             (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
391             (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
392             (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
393             (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
394             (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
395             (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
396             (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
397             (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
398             (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
399             (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
400             (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
401             (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
402             (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
403             (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
404             (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
405             (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
406             (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
407             (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
408             (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
409             (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
410             (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
411             (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
412             (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
413             (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
414             (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
415             (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
416             (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
417             (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
418             (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
419             (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
420             (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
421             (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
422             (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
423             (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
424             (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
425             (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
426             (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
427             (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
428             (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
429             (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
430             (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
431             (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
432             (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
433             (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
434             (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
435             (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
436             (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
437             (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
438             (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
439             (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
440             (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
441             (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
442     };
443 
444     @Rule
445     public ActivityScenarioRule mActivityScenarioRule =
446             new ActivityScenarioRule(WebViewCtsActivity.class);
447 
448     private WebViewCtsActivity mActivity;
449 
450     private WebView mWebView;
451     private SharedSdkWebServer mWebServer;
452     private WebViewOnUiThread mOnUiThread;
453 
454     @Before
setUp()455     public void setUp() throws Exception {
456         mWebView = getTestEnvironment().getWebView();
457         mOnUiThread = new WebViewOnUiThread(mWebView);
458     }
459 
460     @After
cleanup()461     public void cleanup() throws Exception {
462         if (mOnUiThread != null) {
463             mOnUiThread.cleanUp();
464         }
465         if (mWebServer != null) {
466             stopWebServer(mWebServer);
467         }
468         mActivity = null;
469     }
470 
471     @Override
createTestEnvironment()472     protected SharedWebViewTestEnvironment createTestEnvironment() {
473         Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
474 
475         SharedWebViewTestEnvironment.Builder builder = new SharedWebViewTestEnvironment.Builder();
476 
477         mActivityScenarioRule
478                 .getScenario()
479                 .onActivity(
480                         activity -> {
481                             mActivity = (WebViewCtsActivity) activity;
482 
483                             WebView webView = mActivity.getWebView();
484                             builder.setHostAppInvoker(
485                                             SharedWebViewTestEnvironment.createHostAppInvoker(
486                                                     mActivity))
487                                     .setContext(mActivity)
488                                     .setWebView(webView);
489                         });
490 
491         SharedWebViewTestEnvironment environment = builder.build();
492 
493         if (environment.getWebView() != null) {
494             new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
495                 @Override
496                 protected boolean check() {
497                     return mActivity.hasWindowFocus();
498                 }
499             }.run();
500             File f = mActivity.getFileStreamPath("snapshot");
501             if (f.exists()) {
502                 f.delete();
503             }
504         }
505         return environment;
506     }
507 
stopWebServer(SharedSdkWebServer webServer)508     private void stopWebServer(SharedSdkWebServer webServer) throws Exception {
509         assertNotNull(webServer);
510         ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
511         ThreadPolicy tmpPolicy = new ThreadPolicy.Builder(oldPolicy)
512                 .permitNetwork()
513                 .build();
514         StrictMode.setThreadPolicy(tmpPolicy);
515         webServer.shutdown();
516         webServer = null;
517         StrictMode.setThreadPolicy(oldPolicy);
518     }
519 
520     @Test
testInsecureSiteClearsCertificate()521     public void testInsecureSiteClearsCertificate() throws Throwable {
522         final class MockWebViewClient extends WaitForLoadedClient {
523             public MockWebViewClient() {
524                 super(mOnUiThread);
525             }
526             @Override
527             public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
528                 handler.proceed();
529             }
530         }
531 
532         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
533         mOnUiThread.setWebViewClient(new MockWebViewClient());
534         mOnUiThread.loadUrlAndWaitForCompletion(
535                 mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
536         SslCertificate cert = mOnUiThread.getCertificate();
537         assertNotNull(cert);
538         assertEquals("Android", cert.getIssuedTo().getUName());
539 
540         stopWebServer(mWebServer);
541 
542         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
543         mOnUiThread.loadUrlAndWaitForCompletion(
544                 mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
545         assertNull(mOnUiThread.getCertificate());
546     }
547 
548     @Test
testSecureSiteSetsCertificate()549     public void testSecureSiteSetsCertificate() throws Throwable {
550         SharedWebViewTestEnvironment testEnvironment = getTestEnvironment();
551 
552         final class MockWebViewClient extends WaitForLoadedClient {
553             public MockWebViewClient() {
554                 super(mOnUiThread);
555             }
556             @Override
557             public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
558                 handler.proceed();
559             }
560         }
561 
562         mWebServer = testEnvironment.getSetupWebServer(SslMode.INSECURE);
563         mOnUiThread.loadUrlAndWaitForCompletion(
564                 mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
565         assertNull(mOnUiThread.getCertificate());
566 
567         stopWebServer(mWebServer);
568 
569         mWebServer = testEnvironment.getSetupWebServer(SslMode.NO_CLIENT_AUTH);
570         mOnUiThread.setWebViewClient(new MockWebViewClient());
571         mOnUiThread.loadUrlAndWaitForCompletion(
572                 mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
573         SslCertificate cert = mOnUiThread.getCertificate();
574         assertNotNull(cert);
575         assertEquals("Android", cert.getIssuedTo().getUName());
576     }
577 
578     @Test
testClearSslPreferences()579     public void testClearSslPreferences() throws Throwable {
580         // Load the first page. We expect a call to
581         // WebViewClient.onReceivedSslError().
582         final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
583         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
584         final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
585         mOnUiThread.setWebViewClient(webViewClient);
586         mOnUiThread.clearSslPreferences();
587         mOnUiThread.loadUrlAndWaitForCompletion(url);
588         assertTrue("onReceivedSslError should be called",
589                 webViewClient.wasOnReceivedSslErrorCalled());
590 
591         // Load the page again. We expect another call to
592         // WebViewClient.onReceivedSslError() since we cleared sslpreferences.
593         mOnUiThread.clearSslPreferences();
594         webViewClient.resetCallCounts();
595         mOnUiThread.loadUrlAndWaitForCompletion(url);
596         assertTrue("onReceivedSslError should be called again after clearing SSL preferences",
597                 webViewClient.wasOnReceivedSslErrorCalled());
598         assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
599 
600         // Load the page once again, without clearing the sslpreferences.
601         // Make sure we do not get the callback.
602         webViewClient.resetCallCounts();
603         mOnUiThread.loadUrlAndWaitForCompletion(url);
604         assertFalse("onReceivedSslError should not be called when SSL preferences are not cleared",
605                 webViewClient.wasOnReceivedSslErrorCalled());
606         assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
607     }
608 
609     @Test
testOnReceivedSslError()610     public void testOnReceivedSslError() throws Throwable {
611         final class MockWebViewClient extends WaitForLoadedClient {
612             private String mErrorUrl;
613             private WebView mWebView;
614 
615             public MockWebViewClient() {
616                 super(mOnUiThread);
617             }
618             @Override
619             public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
620                 mWebView = view;
621                 mErrorUrl = error.getUrl();
622                 handler.proceed();
623             }
624             public String errorUrl() {
625                 return mErrorUrl;
626             }
627             public WebView webView() {
628                 return mWebView;
629             }
630         }
631 
632         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
633         final String errorUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
634         final MockWebViewClient webViewClient = new MockWebViewClient();
635         mOnUiThread.setWebViewClient(webViewClient);
636         mOnUiThread.clearSslPreferences();
637         mOnUiThread.loadUrlAndWaitForCompletion(errorUrl);
638 
639         assertEquals(mWebView, webViewClient.webView());
640         assertEquals(errorUrl, webViewClient.errorUrl());
641     }
642 
643     @Test
testOnReceivedSslErrorProceed()644     public void testOnReceivedSslErrorProceed() throws Throwable {
645         final class MockWebViewClient extends WaitForLoadedClient {
646             public MockWebViewClient() {
647                 super(mOnUiThread);
648             }
649             @Override
650             public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
651                 handler.proceed();
652             }
653         }
654 
655         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
656         final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
657         mOnUiThread.setWebViewClient(new MockWebViewClient());
658         mOnUiThread.loadUrlAndWaitForCompletion(url);
659         assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
660     }
661 
662     @Test
testOnReceivedSslErrorCancel()663     public void testOnReceivedSslErrorCancel() throws Throwable {
664         final class MockWebViewClient extends WaitForLoadedClient {
665             public MockWebViewClient() {
666                 super(mOnUiThread);
667             }
668             @Override
669             public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
670                 handler.cancel();
671             }
672         }
673 
674         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
675         final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
676         mOnUiThread.setWebViewClient(new MockWebViewClient());
677         mOnUiThread.clearSslPreferences();
678         mOnUiThread.loadUrlAndWaitForCompletion(url);
679         assertNotEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
680     }
681 
682     @Test
testSslErrorProceedResponseReusedForSameHost()683     public void testSslErrorProceedResponseReusedForSameHost() throws Throwable {
684         // Load the first page. We expect a call to
685         // WebViewClient.onReceivedSslError().
686         final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
687         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
688         final String firstUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
689         mOnUiThread.setWebViewClient(webViewClient);
690         mOnUiThread.clearSslPreferences();
691         mOnUiThread.loadUrlAndWaitForCompletion(firstUrl);
692         assertTrue("onReceivedSslError should be called on loading first page",
693                 webViewClient.wasOnReceivedSslErrorCalled());
694 
695         // Load the second page. We don't expect a call to
696         // WebViewClient.onReceivedSslError(), but the page should load.
697         webViewClient.resetCallCounts();
698         final String sameHostUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL2);
699         mOnUiThread.loadUrlAndWaitForCompletion(sameHostUrl);
700         assertFalse("onReceivedSslError should not be called on loading second page",
701                 webViewClient.wasOnReceivedSslErrorCalled());
702         assertEquals("Second page", mOnUiThread.getTitle());
703     }
704 
705     @Test
testSslErrorProceedResponseNotReusedForDifferentHost()706     public void testSslErrorProceedResponseNotReusedForDifferentHost() throws Throwable {
707         // Load the first page. We expect a call to
708         // WebViewClient.onReceivedSslError().
709         final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
710         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
711         final String firstUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
712         mOnUiThread.setWebViewClient(webViewClient);
713         mOnUiThread.clearSslPreferences();
714         mOnUiThread.loadUrlAndWaitForCompletion(firstUrl);
715         assertTrue("onReceivedSslError should be called when request is sent to localhost",
716                 webViewClient.wasOnReceivedSslErrorCalled());
717 
718         // Load the second page. We expect another call to
719         // WebViewClient.onReceivedSslError().
720         webViewClient.resetCallCounts();
721         // The test server uses the host "localhost". "127.0.0.1" works as an
722         // alias, but will be considered unique by the WebView.
723         final String differentHostUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL2).replace(
724                 "localhost", "127.0.0.1");
725         mOnUiThread.loadUrlAndWaitForCompletion(differentHostUrl);
726         assertTrue("onReceivedSslError should be called when request is sent to 127.0.0.1",
727                 webViewClient.wasOnReceivedSslErrorCalled());
728         assertEquals("Second page", mOnUiThread.getTitle());
729     }
730 
731     @Test
testSecureServerRequestingClientCertDoesNotCancelRequest()732     public void testSecureServerRequestingClientCertDoesNotCancelRequest() throws Throwable {
733         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.WANTS_CLIENT_AUTH);
734         final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
735         final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
736         mOnUiThread.setWebViewClient(webViewClient);
737         mOnUiThread.clearSslPreferences();
738         mOnUiThread.loadUrlAndWaitForCompletion(url);
739         // Page loaded OK...
740         assertTrue("onReceivedSslError should be called",
741                 webViewClient.wasOnReceivedSslErrorCalled());
742         assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
743         assertEquals(0, webViewClient.onReceivedErrorCode());
744     }
745 
746     @Test
testSecureServerRequiringClientCertDoesCancelRequest()747     public void testSecureServerRequiringClientCertDoesCancelRequest() throws Throwable {
748         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
749         final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
750         final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
751         mOnUiThread.setWebViewClient(webViewClient);
752         mOnUiThread.clearSslPreferences();
753         loadUrlUntilError(webViewClient, url, WebViewClient.ERROR_FAILED_SSL_HANDSHAKE);
754         // Page NOT loaded OK...
755         //
756         // In this test, we expect both a recoverable and non-recoverable error:
757         //
758         //  1. WebView does not trust the test server's certificate. This is a recoverable error, so
759         //     WebView invokes #onReceivedSslError (and the WebViewClient calls #proceed). We don't
760         //     specifically intend to test this part of the scenario, but we can't easily mock out
761         //     WebView's certificate roots.
762         //  2. WebView proceeds with the handshake without providing client authentication. The
763         //     server fails the client. This is non-recoverable, so WebView invokes
764         //     #onReceivedError.
765         //
766         // We only assert the second error, since earlier WebView versions had a bug in which
767         // WebView hit error 2 first, which prevented it from hitting error 1.
768         assertFalse("Title should not be updated, since page load should have failed",
769                 TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
770     }
771 
772     @Test
testProceedClientCertRequest()773     public void testProceedClientCertRequest() throws Throwable {
774         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
775         String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
776         final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(mOnUiThread);
777         mOnUiThread.setWebViewClient(webViewClient);
778         clearClientCertPreferences();
779         mOnUiThread.loadUrlAndWaitForCompletion(url);
780         assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
781 
782         // Test that the user's response for this server is kept in cache. Load a different
783         // page from the same server and make sure we don't receive a client cert request callback.
784         webViewClient.resetCallCounts();
785         url = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
786         mOnUiThread.loadUrlAndWaitForCompletion(url);
787         assertEquals(TestHtmlConstants.HTML_URL1_TITLE, mOnUiThread.getTitle());
788         assertEquals("onReceivedClientCertRequest should not be called",
789                 0, webViewClient.getClientCertRequestCount());
790 
791         // Now clear the cache and reload the page. We should receive a new callback.
792         webViewClient.resetCallCounts();
793         clearClientCertPreferences();
794         mOnUiThread.loadUrlAndWaitForCompletion(url);
795         assertEquals(TestHtmlConstants.HTML_URL1_TITLE, mOnUiThread.getTitle());
796         assertEquals("onReceivedClientCertRequest should be called once",
797                 1, webViewClient.getClientCertRequestCount());
798     }
799 
800     @Test
testProceedClientCertRequestKeyWithAndroidKeystoreKey()801     public void testProceedClientCertRequestKeyWithAndroidKeystoreKey() throws Throwable {
802         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
803         String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
804         final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(
805                 mOnUiThread,
806                 true // use an Android Keystore backed private key
807                 );
808         mOnUiThread.setWebViewClient(webViewClient);
809         clearClientCertPreferences();
810         mOnUiThread.loadUrlAndWaitForCompletion(url);
811         assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
812 
813         // Test that the user's response for this server is kept in cache. Load a different
814         // page from the same server and make sure we don't receive a client cert request callback.
815         webViewClient.resetCallCounts();
816         url = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
817         mOnUiThread.loadUrlAndWaitForCompletion(url);
818         assertEquals(TestHtmlConstants.HTML_URL1_TITLE, mOnUiThread.getTitle());
819         assertEquals("onReceivedClientCertRequest should not be called",
820                 0, webViewClient.getClientCertRequestCount());
821 
822         // Now clear the cache and reload the page. We should receive a new callback.
823         webViewClient.resetCallCounts();
824         clearClientCertPreferences();
825         mOnUiThread.loadUrlAndWaitForCompletion(url);
826         assertEquals(TestHtmlConstants.HTML_URL1_TITLE, mOnUiThread.getTitle());
827         assertEquals("onReceivedClientCertRequest should be called once",
828                 1, webViewClient.getClientCertRequestCount());
829     }
830 
831     /**
832      * Loads a url until a specific error code. This is meant to be used when two different errors
833      * can race. Specifically, this is meant to be used to workaround the TLS 1.3 (Android Q and
834      * above) race condition where a server <b>may</b> close the connection at the same time the
835      * client sends the HTTP request, emitting {@code ERROR_CONNECT} instead of {@code
836      * ERROR_FAILED_SSL_HANDSHAKE}.
837      */
loadUrlUntilError(SslErrorWebViewClient client, String url, int expectedErrorCode)838     private void loadUrlUntilError(SslErrorWebViewClient client, String url,
839             int expectedErrorCode) {
840         int maxTries = 40;
841         for (int i = 0; i < maxTries; i++) {
842             mOnUiThread.loadUrlAndWaitForCompletion(url);
843             if (client.onReceivedErrorCode() == expectedErrorCode) {
844                 return;
845             }
846         }
847         throw new RuntimeException(
848                 "Reached max number of tries and never saw error " + expectedErrorCode);
849     }
850 
851     @Test
testIgnoreClientCertRequest()852     public void testIgnoreClientCertRequest() throws Throwable {
853         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
854         String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
855         final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(mOnUiThread);
856         mOnUiThread.setWebViewClient(webViewClient);
857         clearClientCertPreferences();
858         // Ignore the request. Load should fail.
859         webViewClient.setAction(ClientCertWebViewClient.IGNORE);
860         loadUrlUntilError(webViewClient, url, WebViewClient.ERROR_FAILED_SSL_HANDSHAKE);
861         assertNotEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
862         // At least one of the loads done by loadUrlUntilError() should produce
863         // onReceivedClientCertRequest.
864         assertTrue("onReceivedClientCertRequest should be called at least once",
865                 webViewClient.getClientCertRequestCount() >= 1);
866 
867         // Load a different page from the same domain, ignoring the request. We should get a callback,
868         // and load should fail.
869         webViewClient.resetCallCounts();
870         url = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
871         loadUrlUntilError(webViewClient, url, WebViewClient.ERROR_FAILED_SSL_HANDSHAKE);
872         assertNotEquals(TestHtmlConstants.HTML_URL1_TITLE, mOnUiThread.getTitle());
873         // At least one of the loads done by loadUrlUntilError() should produce
874         // onReceivedClientCertRequest.
875         assertTrue("onReceivedClientCertRequest should be called at least once for second URL",
876                 webViewClient.getClientCertRequestCount() >= 1);
877 
878         // Reload, proceeding the request. Load should succeed.
879         webViewClient.setAction(ClientCertWebViewClient.PROCEED);
880         url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
881         mOnUiThread.loadUrlAndWaitForCompletion(url);
882         assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
883     }
884 
885     @Test
testCancelClientCertRequest()886     public void testCancelClientCertRequest() throws Throwable {
887         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
888         final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
889         final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(mOnUiThread);
890         mOnUiThread.setWebViewClient(webViewClient);
891         clearClientCertPreferences();
892         // Cancel the request. Load should fail.
893         webViewClient.setAction(ClientCertWebViewClient.CANCEL);
894         loadUrlUntilError(webViewClient, url, WebViewClient.ERROR_FAILED_SSL_HANDSHAKE);
895         assertNotEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
896         // At least one of the loads done by loadUrlUntilError() should produce
897         // onReceivedClientCertRequest.
898         assertTrue("onReceivedClientCertRequest should be called at least once",
899                 webViewClient.getClientCertRequestCount() >= 1);
900 
901         // Reload. The request should fail without generating a new callback.
902         webViewClient.resetCallCounts();
903         loadUrlUntilError(webViewClient, url, WebViewClient.ERROR_FAILED_SSL_HANDSHAKE);
904         // None of the loads done by loadUrlUntilError() should produce onReceivedClientCertRequest.
905         assertEquals("onReceivedClientCertRequest should not be called for reload",
906                 0, webViewClient.getClientCertRequestCount());
907         assertNotEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
908     }
909 
910     @Test
testClientCertIssuersReceivedCorrectly()911     public void testClientCertIssuersReceivedCorrectly() throws Throwable {
912         mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH,
913             FAKE_RSA_CA_1, 0, 0);
914         final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
915         final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(mOnUiThread);
916         mOnUiThread.setWebViewClient(webViewClient);
917         clearClientCertPreferences();
918         mOnUiThread.loadUrlAndWaitForCompletion(url);
919         // Verify that issuers sent by the server are received correctly
920         CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
921         X509Certificate  cert = (X509Certificate) certFactory.generateCertificate(
922                                 new ByteArrayInputStream(FAKE_RSA_CA_1));
923         Principal[] principals = webViewClient.getPrincipals();
924         assertEquals(1, principals.length);
925         // TODO: should we issue getIssuerX500Principal instead?
926         assertEquals(cert.getIssuerDN(), principals[0]);
927     }
928 
clearClientCertPreferences()929     private void clearClientCertPreferences() {
930         final AtomicBoolean cleared = new AtomicBoolean(false);
931         WebView.clearClientCertPreferences(new Runnable() {
932             @Override
933             public void run() {
934                 cleared.set(true);
935             }
936         });
937         // Wait until clearclientcertpreferences clears the preferences. Generally this is just a
938         // thread hopping.
939         new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
940             @Override
941             protected boolean check() {
942                 return cleared.get();
943             }
944         }.run();
945     }
946 
947     // Note that this class is not thread-safe.
948     static class SslErrorWebViewClient extends WaitForLoadedClient {
949         private boolean mWasOnReceivedSslErrorCalled;
950         private String mErrorUrl;
951         private int mErrorCode;
952 
SslErrorWebViewClient(WebViewOnUiThread onUiThread)953         public SslErrorWebViewClient(WebViewOnUiThread onUiThread) {
954             super(onUiThread);
955         }
956         @Override
onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)957         public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
958             mWasOnReceivedSslErrorCalled = true;
959             mErrorUrl = error.getUrl();
960             handler.proceed();
961         }
962         @Override
onReceivedError(WebView view, int errorCode, String description, String failingUrl)963         public void onReceivedError(WebView view, int errorCode, String description,
964                 String failingUrl) {
965             mErrorCode = errorCode;
966         }
967         @CallSuper
resetCallCounts()968         public void resetCallCounts() {
969             mWasOnReceivedSslErrorCalled = false;
970             mErrorUrl = null;
971             mErrorCode = 0;
972         }
wasOnReceivedSslErrorCalled()973         public boolean wasOnReceivedSslErrorCalled() {
974             return mWasOnReceivedSslErrorCalled;
975         }
errorUrl()976         public String errorUrl() {
977             return mErrorUrl;
978         }
onReceivedErrorCode()979         public int onReceivedErrorCode() {
980             return mErrorCode;
981         }
982     }
983 
984     // Modifies the default behavior of SslErrorWebViewClient to accept the request, and provide
985     // certs.
986     static class ClientCertWebViewClient extends SslErrorWebViewClient {
987         // User Actions
988         public static final int PROCEED = 1;
989         public static final int CANCEL = 2;
990         public static final int IGNORE = 3;
991 
992         private final boolean mKeyFromAndroidKeystore;
993 
994         private int mClientCertRequests;
995         private int mAction = PROCEED;
996         private Principal[] mPrincipals;
997 
ClientCertWebViewClient(WebViewOnUiThread onUiThread)998         public ClientCertWebViewClient(WebViewOnUiThread onUiThread) {
999             this(onUiThread, false);
1000         }
1001 
ClientCertWebViewClient(WebViewOnUiThread onUiThread, boolean keyFromAndroidKeystore)1002         public ClientCertWebViewClient(WebViewOnUiThread onUiThread,
1003                 boolean keyFromAndroidKeystore) {
1004             super(onUiThread);
1005             mKeyFromAndroidKeystore = keyFromAndroidKeystore;
1006         }
1007 
getClientCertRequestCount()1008         public int getClientCertRequestCount() {
1009             return mClientCertRequests;
1010         }
1011 
getPrincipals()1012         public Principal[] getPrincipals() {
1013             return mPrincipals;
1014         }
1015 
setAction(int action)1016         public void setAction(int action) {
1017             mAction = action;
1018         }
1019 
1020         @Override
resetCallCounts()1021         public void resetCallCounts() {
1022             super.resetCallCounts();
1023             mClientCertRequests = 0;
1024             mPrincipals = null;
1025         }
1026 
1027         @Override
onReceivedClientCertRequest(WebView view, ClientCertRequest request)1028         public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
1029             mClientCertRequests++;
1030             mPrincipals = request.getPrincipals();
1031             if (mAction == IGNORE) {
1032                 request.ignore();
1033                 return;
1034             }
1035             if (mAction == CANCEL) {
1036                 request.cancel();
1037                 return;
1038             }
1039             if (mAction == PROCEED) {
1040                 try {
1041                     CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
1042                     X509Certificate[] certChain =  new X509Certificate[] {
1043                             (X509Certificate) certFactory.generateCertificate(
1044                                     new ByteArrayInputStream(FAKE_RSA_USER_1)),
1045                             (X509Certificate) certFactory.generateCertificate(
1046                                     new ByteArrayInputStream(FAKE_RSA_CA_1))
1047                     };
1048                     KeyFactory keyFactory = KeyFactory.getInstance("RSA");
1049                     PrivateKey key = keyFactory.generatePrivate(
1050                         new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
1051 
1052                     if (mKeyFromAndroidKeystore) {
1053                         // Key needs to be backed by Android Keystore -- import it there.
1054                         KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
1055                         keyStore.load(null);
1056                         Log.d(LOGTAG, "Importing private key into Android Keystore...");
1057                         keyStore.setEntry(
1058                                 "fake1",
1059                                 new KeyStore.PrivateKeyEntry(key, certChain),
1060                                 null);
1061 
1062                         key = (PrivateKey) keyStore.getKey("fake1", null);
1063                         Log.i(LOGTAG, "Imported private key into Android Keystore. key: " + key);
1064                     }
1065 
1066                     request.proceed(key, certChain);
1067                     return;
1068                 } catch (Exception e) {
1069                     throw new RuntimeException(e);
1070                 }
1071             }
1072             throw new IllegalStateException("unknown action");
1073         }
1074     }
1075 }
1076