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