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