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