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