1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)package org.chromium.android_webview; 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.net.http.SslCertificate; 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.net.http.SslError; 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport android.util.Log; 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.webkit.ValueCallback; 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.base.CalledByNative; 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.base.JNINamespace; 140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport org.chromium.base.ThreadUtils; 150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport org.chromium.net.AndroidPrivateKey; 160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport org.chromium.net.DefaultAndroidKeyStore; 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport java.security.Principal; 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport java.security.PrivateKey; 200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport java.security.cert.CertificateEncodingException; 210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport java.security.cert.X509Certificate; 220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport javax.security.auth.x500.X500Principal; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This class handles the JNI communication logic for the the AwContentsClient class. 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Both the Java and the native peers of AwContentsClientBridge are owned by the 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * corresponding AwContents instances. This class and its native peer are connected 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * via weak references. The native AwContentsClientBridge sets up and clear these weak 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * references. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)@JNINamespace("android_webview") 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public class AwContentsClientBridge { 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch static final String TAG = "AwContentsClientBridge"; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private AwContentsClient mClient; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The native peer of this object. 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private long mNativeContentsClientBridge; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private DefaultAndroidKeyStore mLocalKeyStore; 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private ClientCertLookupTable mLookupTable; 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Used for mocking this class in tests. 450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch protected AwContentsClientBridge(DefaultAndroidKeyStore keyStore, 460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ClientCertLookupTable table) { 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mLocalKeyStore = keyStore; 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mLookupTable = table; 490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public AwContentsClientBridge(AwContentsClient client, DefaultAndroidKeyStore keyStore, 520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ClientCertLookupTable table) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert client != null; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mClient = client; 550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mLocalKeyStore = keyStore; 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mLookupTable = table; 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /** 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * Callback to communicate clientcertificaterequest back to the AwContentsClientBridge. 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * The public methods should be called on UI thread. 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * A request can not be proceeded, ignored or canceled more than once. Doing this 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * is a programming error and causes an exception. 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch */ 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public class ClientCertificateRequestCallback { 660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private int mId; 680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private String mHost; 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private int mPort; 700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private boolean mIsCalled; 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public ClientCertificateRequestCallback(int id, String host, int port) { 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mId = id; 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mHost = host; 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mPort = port; 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void proceed(final PrivateKey privateKey, final X509Certificate[] chain) { 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ThreadUtils.runOnUiThread(new Runnable() { 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch @Override 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void run() { 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proceedOnUiThread(privateKey, chain); 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch }); 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void ignore() { 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ThreadUtils.runOnUiThread(new Runnable() { 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch @Override 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void run() { 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ignoreOnUiThread(); 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch }); 940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void cancel() { 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ThreadUtils.runOnUiThread(new Runnable() { 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch @Override 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void run() { 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch cancelOnUiThread(); 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch }); 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private void proceedOnUiThread(PrivateKey privateKey, X509Certificate[] chain) { 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch checkIfCalled(); 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch AndroidPrivateKey key = mLocalKeyStore.createKey(privateKey); 1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (key == null || chain == null || chain.length == 0) { 1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Log.w(TAG, "Empty client certificate chain?"); 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch provideResponse(null, null); 1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Encode the certificate chain. 1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch byte[][] encodedChain = new byte[chain.length][]; 1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch try { 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (int i = 0; i < chain.length; ++i) { 1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch encodedChain[i] = chain[i].getEncoded(); 1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } catch (CertificateEncodingException e) { 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Log.w(TAG, "Could not retrieve encoded certificate chain: " + e); 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch provideResponse(null, null); 1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mLookupTable.allow(mHost, mPort, key, encodedChain); 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch provideResponse(key, encodedChain); 1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private void ignoreOnUiThread() { 1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch checkIfCalled(); 1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch provideResponse(null, null); 1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private void cancelOnUiThread() { 1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch checkIfCalled(); 1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mLookupTable.deny(mHost, mPort); 1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch provideResponse(null, null); 1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private void checkIfCalled() { 1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (mIsCalled) { 1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch throw new IllegalStateException("The callback was already called."); 1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mIsCalled = true; 1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private void provideResponse(AndroidPrivateKey androidKey, byte[][] certChain) { 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mNativeContentsClientBridge == 0) return; 1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch nativeProvideClientCertificateResponse(mNativeContentsClientBridge, mId, 1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch certChain, androidKey); 1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Used by the native peer to set/reset a weak ref to the native peer. 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @CalledByNative 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private void setNativeContentsClientBridge(long nativeContentsClientBridge) { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mNativeContentsClientBridge = nativeContentsClientBridge; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If returns false, the request is immediately canceled, and any call to proceedSslError 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // has no effect. If returns true, the request should be canceled or proceeded using 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // proceedSslError(). 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Unlike the webview classic, we do not keep keep a database of certificates that 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // are allowed by the user, because this functionality is already handled via 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ssl_policy in native layers. 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @CalledByNative 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private boolean allowCertificateError(int certError, byte[] derBytes, final String url, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int id) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final SslCertificate cert = SslUtil.getCertificateFromDerBytes(derBytes); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (cert == null) { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if the certificate or the client is null, cancel the request 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final SslError sslError = SslUtil.sslErrorFromNetErrorCode(certError, cert, url); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ValueCallback<Boolean> callback = new ValueCallback<Boolean>() { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void onReceiveValue(final Boolean value) { 1800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ThreadUtils.runOnUiThread(new Runnable() { 1810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch @Override 1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public void run() { 1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch proceedSslError(value.booleanValue(), id); 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch }); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mClient.onReceivedSslError(callback, sslError); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private void proceedSslError(boolean proceed, int id) { 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mNativeContentsClientBridge == 0) return; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nativeProceedSslError(mNativeContentsClientBridge, proceed, id); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Intentionally not private for testing the native peer of this class. 1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch @CalledByNative 1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch protected void selectClientCertificate(final int id, final String[] keyTypes, 2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch byte[][] encodedPrincipals, final String host, final int port) { 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) assert mNativeContentsClientBridge != 0; 2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ClientCertLookupTable.Cert cert = mLookupTable.getCertData(host, port); 2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (mLookupTable.isDenied(host, port)) { 2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch nativeProvideClientCertificateResponse(mNativeContentsClientBridge, id, 2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch null, null); 2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (cert != null) { 2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch nativeProvideClientCertificateResponse(mNativeContentsClientBridge, id, 2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch cert.certChain, cert.privateKey); 2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Build the list of principals from encoded versions. 2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Principal[] principals = null; 2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (encodedPrincipals.length > 0) { 2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch principals = new X500Principal[encodedPrincipals.length]; 2170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (int n = 0; n < encodedPrincipals.length; n++) { 2180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch try { 2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch principals[n] = new X500Principal(encodedPrincipals[n]); 2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } catch (IllegalArgumentException e) { 2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Log.w(TAG, "Exception while decoding issuers list: " + e); 2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch nativeProvideClientCertificateResponse(mNativeContentsClientBridge, id, 2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch null, null); 2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch final ClientCertificateRequestCallback callback = 2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new ClientCertificateRequestCallback(id, host, port); 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mClient.onReceivedClientCertRequest(callback, keyTypes, principals, host, port); 2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @CalledByNative 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private void handleJsAlert(String url, String message, int id) { 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) JsResultHandler handler = new JsResultHandler(this, id); 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mClient.handleJsAlert(url, message, handler); 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @CalledByNative 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private void handleJsConfirm(String url, String message, int id) { 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) JsResultHandler handler = new JsResultHandler(this, id); 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mClient.handleJsConfirm(url, message, handler); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @CalledByNative 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private void handleJsPrompt(String url, String message, String defaultValue, int id) { 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) JsResultHandler handler = new JsResultHandler(this, id); 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mClient.handleJsPrompt(url, message, defaultValue, handler); 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @CalledByNative 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private void handleJsBeforeUnload(String url, String message, int id) { 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) JsResultHandler handler = new JsResultHandler(this, id); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mClient.handleJsBeforeUnload(url, message, handler); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) @CalledByNative 260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private boolean shouldOverrideUrlLoading(String url) { 261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return mClient.shouldOverrideUrlLoading(url); 262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void confirmJsResult(int id, String prompt) { 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mNativeContentsClientBridge == 0) return; 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) nativeConfirmJsResult(mNativeContentsClientBridge, id, prompt); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void cancelJsResult(int id) { 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mNativeContentsClientBridge == 0) return; 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) nativeCancelJsResult(mNativeContentsClientBridge, id); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) //-------------------------------------------------------------------------------------------- 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Native methods 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) //-------------------------------------------------------------------------------------------- 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private native void nativeProceedSslError(long nativeAwContentsClientBridge, boolean proceed, 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int id); 2790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private native void nativeProvideClientCertificateResponse(long nativeAwContentsClientBridge, 2800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int id, byte[][] certChain, AndroidPrivateKey androidKey); 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private native void nativeConfirmJsResult(long nativeAwContentsClientBridge, int id, 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) String prompt); 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private native void nativeCancelJsResult(long nativeAwContentsClientBridge, int id); 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 286