Cherry-pick "Reject rather than abort client certificates"

Bug 11375270

Taken from https://codereview.chromium.org/42583002/ PS2

Original description:

Reject rather than abort client certificates

The default behavior in the existing implementation was to reject the
client cert request but allow the SSL connection to proceed (so allowing
the server to choose policy on how to handle this scenario). Implement
the content callbacks to acheive the same.

Change-Id: Id9b091a876b9e1ed2f7092876511987cd1fa4a74
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index 3549929..0c430ec 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -27,6 +27,7 @@
 #include "content/public/common/url_constants.h"
 #include "grit/ui_resources.h"
 #include "net/android/network_library.h"
+#include "net/ssl/ssl_cert_request_info.h"
 #include "net/ssl/ssl_info.h"
 #include "ui/base/l10n/l10n_util_android.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -339,6 +340,18 @@
     *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
 }
 
+void AwContentBrowserClient::SelectClientCertificate(
+      int render_process_id,
+      int render_view_id,
+      const net::HttpNetworkSession* network_session,
+      net::SSLCertRequestInfo* cert_request_info,
+      const base::Callback<void(net::X509Certificate*)>& callback) {
+  LOG(INFO) << "Client certificate request from "
+        << cert_request_info->host_and_port
+        << " rejected. (Client certificates not supported in WebView)";
+  callback.Run(NULL);
+}
+
 WebKit::WebNotificationPresenter::Permission
     AwContentBrowserClient::CheckDesktopNotificationPermission(
         const GURL& source_url,
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index 38a6b03..cf92d3a 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -103,6 +103,12 @@
       bool strict_enforcement,
       const base::Callback<void(bool)>& callback,
       content::CertificateRequestResultType* result) OVERRIDE;
+  virtual void SelectClientCertificate(
+      int render_process_id,
+      int render_view_id,
+      const net::HttpNetworkSession* network_session,
+      net::SSLCertRequestInfo* cert_request_info,
+      const base::Callback<void(net::X509Certificate*)>& callback) OVERRIDE;
   virtual WebKit::WebNotificationPresenter::Permission
       CheckDesktopNotificationPermission(
           const GURL& source_url,
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
index 0650c54..5d22c06 100644
--- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
+++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
@@ -280,6 +280,19 @@
   return true;
 }
 
+bool AwResourceDispatcherHostDelegate::AcceptSSLClientCertificateRequest(
+    net::URLRequest* request,
+    net::SSLCertRequestInfo* cert_info) {
+  // WebView does not support client certificate selection, however it does
+  // send a no-certificate response to the server to allow it decide how to
+  // proceed. The base class returns false here, which causes the entire
+  // resource request to be abort. We don't want that, so we must return true
+  // here (and subsequently complete the request in
+  // AwContentBrowserClient::SelectClientCertificate) to get the intended
+  // behavior.
+  return true;
+}
+
 content::ResourceDispatcherHostLoginDelegate*
     AwResourceDispatcherHostDelegate::CreateLoginDelegate(
         net::AuthChallengeInfo* auth_info,
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
index 8790ea3..949aa29 100644
--- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
+++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
@@ -49,6 +49,10 @@
       ScopedVector<content::ResourceThrottle>* throttles) OVERRIDE;
   virtual bool AcceptAuthRequest(net::URLRequest* request,
                                  net::AuthChallengeInfo* auth_info) OVERRIDE;
+  virtual bool AcceptSSLClientCertificateRequest(
+      net::URLRequest* request,
+      net::SSLCertRequestInfo* cert_info) OVERRIDE;
+
   virtual content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
       net::AuthChallengeInfo* auth_info,
       net::URLRequest* request) OVERRIDE;