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