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