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