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