Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(375)

Side by Side Diff: android_webview/native/aw_contents_client_bridge.cc

Issue 859213006: Cancel client auth requests when not promptable. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@client-auth-cancel-1
Patch Set: worker_common.js was missing a license header (also a rebase) Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "android_webview/native/aw_contents_client_bridge.h" 5 #include "android_webview/native/aw_contents_client_bridge.h"
6 6
7 #include "android_webview/common/devtools_instrumentation.h" 7 #include "android_webview/common/devtools_instrumentation.h"
8 #include "android_webview/native/aw_contents.h" 8 #include "android_webview/native/aw_contents.h"
9 #include "base/android/jni_android.h" 9 #include "base/android/jni_android.h"
10 #include "base/android/jni_array.h" 10 #include "base/android/jni_array.h"
11 #include "base/android/jni_string.h" 11 #include "base/android/jni_string.h"
12 #include "base/callback_helpers.h" 12 #include "base/callback_helpers.h"
13 #include "base/macros.h"
13 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/client_certificate_delegate.h"
14 #include "content/public/browser/render_process_host.h" 16 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/render_view_host.h" 17 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/web_contents.h" 18 #include "content/public/browser/web_contents.h"
17 #include "crypto/scoped_openssl_types.h" 19 #include "crypto/scoped_openssl_types.h"
18 #include "jni/AwContentsClientBridge_jni.h" 20 #include "jni/AwContentsClientBridge_jni.h"
19 #include "net/android/keystore_openssl.h" 21 #include "net/android/keystore_openssl.h"
20 #include "net/cert/x509_certificate.h" 22 #include "net/cert/x509_certificate.h"
21 #include "net/ssl/openssl_client_key_store.h" 23 #include "net/ssl/openssl_client_key_store.h"
22 #include "net/ssl/ssl_cert_request_info.h" 24 #include "net/ssl/ssl_cert_request_info.h"
23 #include "net/ssl/ssl_client_cert_type.h" 25 #include "net/ssl/ssl_client_cert_type.h"
(...skipping 27 matching lines...) Expand all
51 : java_ref_(env, obj) { 53 : java_ref_(env, obj) {
52 DCHECK(obj); 54 DCHECK(obj);
53 Java_AwContentsClientBridge_setNativeContentsClientBridge( 55 Java_AwContentsClientBridge_setNativeContentsClientBridge(
54 env, obj, reinterpret_cast<intptr_t>(this)); 56 env, obj, reinterpret_cast<intptr_t>(this));
55 } 57 }
56 58
57 AwContentsClientBridge::~AwContentsClientBridge() { 59 AwContentsClientBridge::~AwContentsClientBridge() {
58 JNIEnv* env = AttachCurrentThread(); 60 JNIEnv* env = AttachCurrentThread();
59 61
60 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 62 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
61 if (obj.is_null()) 63 if (!obj.is_null()) {
62 return; 64 // Clear the weak reference from the java peer to the native object since
63 // Clear the weak reference from the java peer to the native object since 65 // it is possible that java object lifetime can exceed the AwContens.
64 // it is possible that java object lifetime can exceed the AwContens. 66 Java_AwContentsClientBridge_setNativeContentsClientBridge(env, obj.obj(),
65 Java_AwContentsClientBridge_setNativeContentsClientBridge(env, obj.obj(), 0); 67 0);
68 }
69
70 for (IDMap<content::ClientCertificateDelegate>::iterator iter(
71 &pending_client_cert_request_delegates_);
72 !iter.IsAtEnd(); iter.Advance()) {
73 delete iter.GetCurrentValue();
74 }
66 } 75 }
67 76
68 void AwContentsClientBridge::AllowCertificateError( 77 void AwContentsClientBridge::AllowCertificateError(
69 int cert_error, 78 int cert_error,
70 net::X509Certificate* cert, 79 net::X509Certificate* cert,
71 const GURL& request_url, 80 const GURL& request_url,
72 const base::Callback<void(bool)>& callback, 81 const base::Callback<void(bool)>& callback,
73 bool* cancel_request) { 82 bool* cancel_request) {
74 83
75 DCHECK_CURRENTLY_ON(BrowserThread::UI); 84 DCHECK_CURRENTLY_ON(BrowserThread::UI);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 LOG(WARNING) << "Ignoring unexpected ssl error proceed callback"; 116 LOG(WARNING) << "Ignoring unexpected ssl error proceed callback";
108 return; 117 return;
109 } 118 }
110 callback->Run(proceed); 119 callback->Run(proceed);
111 pending_cert_error_callbacks_.Remove(id); 120 pending_cert_error_callbacks_.Remove(id);
112 } 121 }
113 122
114 // This method is inspired by SelectClientCertificate() in 123 // This method is inspired by SelectClientCertificate() in
115 // chrome/browser/ui/android/ssl_client_certificate_request.cc 124 // chrome/browser/ui/android/ssl_client_certificate_request.cc
116 void AwContentsClientBridge::SelectClientCertificate( 125 void AwContentsClientBridge::SelectClientCertificate(
117 net::SSLCertRequestInfo* cert_request_info, 126 net::SSLCertRequestInfo* cert_request_info,
118 const SelectCertificateCallback& callback) { 127 scoped_ptr<content::ClientCertificateDelegate> delegate) {
119 DCHECK_CURRENTLY_ON(BrowserThread::UI); 128 DCHECK_CURRENTLY_ON(BrowserThread::UI);
120 129
121 // Add the callback to id map. 130 // Add the callback to id map.
122 int request_id = pending_client_cert_request_callbacks_.Add( 131 int request_id =
123 new SelectCertificateCallback(callback)); 132 pending_client_cert_request_delegates_.Add(delegate.release());
124 // Make sure callback is run on error. 133 // Make sure callback is run on error.
125 base::ScopedClosureRunner guard(base::Bind( 134 base::ScopedClosureRunner guard(base::Bind(
126 &AwContentsClientBridge::HandleErrorInClientCertificateResponse, 135 &AwContentsClientBridge::HandleErrorInClientCertificateResponse,
127 base::Unretained(this), 136 base::Unretained(this),
128 request_id)); 137 request_id));
129 138
130 JNIEnv* env = base::android::AttachCurrentThread(); 139 JNIEnv* env = base::android::AttachCurrentThread();
131 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); 140 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
132 if (obj.is_null()) 141 if (obj.is_null())
133 return; 142 return;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 // This method is inspired by OnSystemRequestCompletion() in 198 // This method is inspired by OnSystemRequestCompletion() in
190 // chrome/browser/ui/android/ssl_client_certificate_request.cc 199 // chrome/browser/ui/android/ssl_client_certificate_request.cc
191 void AwContentsClientBridge::ProvideClientCertificateResponse( 200 void AwContentsClientBridge::ProvideClientCertificateResponse(
192 JNIEnv* env, 201 JNIEnv* env,
193 jobject obj, 202 jobject obj,
194 int request_id, 203 int request_id,
195 jobjectArray encoded_chain_ref, 204 jobjectArray encoded_chain_ref,
196 jobject private_key_ref) { 205 jobject private_key_ref) {
197 DCHECK_CURRENTLY_ON(BrowserThread::UI); 206 DCHECK_CURRENTLY_ON(BrowserThread::UI);
198 207
199 SelectCertificateCallback* callback = 208 content::ClientCertificateDelegate* delegate =
200 pending_client_cert_request_callbacks_.Lookup(request_id); 209 pending_client_cert_request_delegates_.Lookup(request_id);
201 DCHECK(callback); 210 DCHECK(delegate);
211
212 if (encoded_chain_ref == NULL || private_key_ref == NULL) {
213 LOG(ERROR) << "No client certificate selected";
214 pending_client_cert_request_delegates_.Remove(request_id);
215 delegate->ContinueWithCertificate(nullptr);
216 delete delegate;
217 return;
218 }
202 219
203 // Make sure callback is run on error. 220 // Make sure callback is run on error.
204 base::ScopedClosureRunner guard(base::Bind( 221 base::ScopedClosureRunner guard(base::Bind(
205 &AwContentsClientBridge::HandleErrorInClientCertificateResponse, 222 &AwContentsClientBridge::HandleErrorInClientCertificateResponse,
206 base::Unretained(this), 223 base::Unretained(this),
207 request_id)); 224 request_id));
208 if (encoded_chain_ref == NULL || private_key_ref == NULL) { 225
209 LOG(ERROR) << "Client certificate request cancelled";
210 return;
211 }
212 // Convert the encoded chain to a vector of strings. 226 // Convert the encoded chain to a vector of strings.
213 std::vector<std::string> encoded_chain_strings; 227 std::vector<std::string> encoded_chain_strings;
214 if (encoded_chain_ref) { 228 if (encoded_chain_ref) {
215 base::android::JavaArrayOfByteArrayToStringVector( 229 base::android::JavaArrayOfByteArrayToStringVector(
216 env, encoded_chain_ref, &encoded_chain_strings); 230 env, encoded_chain_ref, &encoded_chain_strings);
217 } 231 }
218 232
219 std::vector<base::StringPiece> encoded_chain; 233 std::vector<base::StringPiece> encoded_chain;
220 for (size_t i = 0; i < encoded_chain_strings.size(); ++i) 234 for (size_t i = 0; i < encoded_chain_strings.size(); ++i)
221 encoded_chain.push_back(encoded_chain_strings[i]); 235 encoded_chain.push_back(encoded_chain_strings[i]);
222 236
223 // Create the X509Certificate object from the encoded chain. 237 // Create the X509Certificate object from the encoded chain.
224 scoped_refptr<net::X509Certificate> client_cert( 238 scoped_refptr<net::X509Certificate> client_cert(
225 net::X509Certificate::CreateFromDERCertChain(encoded_chain)); 239 net::X509Certificate::CreateFromDERCertChain(encoded_chain));
226 if (!client_cert.get()) { 240 if (!client_cert.get()) {
227 LOG(ERROR) << "Could not decode client certificate chain"; 241 LOG(ERROR) << "Could not decode client certificate chain";
228 return; 242 return;
229 } 243 }
230 244
231 // Create an EVP_PKEY wrapper for the private key JNI reference. 245 // Create an EVP_PKEY wrapper for the private key JNI reference.
232 crypto::ScopedEVP_PKEY private_key( 246 crypto::ScopedEVP_PKEY private_key(
233 net::android::GetOpenSSLPrivateKeyWrapper(private_key_ref)); 247 net::android::GetOpenSSLPrivateKeyWrapper(private_key_ref));
234 if (!private_key.get()) { 248 if (!private_key.get()) {
235 LOG(ERROR) << "Could not create OpenSSL wrapper for private key"; 249 LOG(ERROR) << "Could not create OpenSSL wrapper for private key";
236 return; 250 return;
237 } 251 }
238 252
253 // Release the guard and |pending_client_cert_request_delegates_| references
254 // to |delegate|.
255 pending_client_cert_request_delegates_.Remove(request_id);
256 ignore_result(guard.Release());
257
239 // RecordClientCertificateKey() must be called on the I/O thread, 258 // RecordClientCertificateKey() must be called on the I/O thread,
240 // before the callback is called with the selected certificate on 259 // before the delegate is called with the selected certificate on
241 // the UI thread. 260 // the UI thread.
242 content::BrowserThread::PostTaskAndReply( 261 content::BrowserThread::PostTaskAndReply(
243 content::BrowserThread::IO, 262 content::BrowserThread::IO, FROM_HERE,
244 FROM_HERE, 263 base::Bind(&RecordClientCertificateKey, client_cert,
245 base::Bind(&RecordClientCertificateKey,
246 client_cert,
247 base::Passed(&private_key)), 264 base::Passed(&private_key)),
248 base::Bind(*callback, client_cert)); 265 base::Bind(&content::ClientCertificateDelegate::ContinueWithCertificate,
249 pending_client_cert_request_callbacks_.Remove(request_id); 266 base::Owned(delegate), client_cert));
250
251 // Release the guard.
252 ignore_result(guard.Release());
253 } 267 }
254 268
255 void AwContentsClientBridge::RunJavaScriptDialog( 269 void AwContentsClientBridge::RunJavaScriptDialog(
256 content::JavaScriptMessageType message_type, 270 content::JavaScriptMessageType message_type,
257 const GURL& origin_url, 271 const GURL& origin_url,
258 const base::string16& message_text, 272 const base::string16& message_text,
259 const base::string16& default_prompt_text, 273 const base::string16& default_prompt_text,
260 const content::JavaScriptDialogManager::DialogClosedCallback& callback) { 274 const content::JavaScriptDialogManager::DialogClosedCallback& callback) {
261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
262 JNIEnv* env = AttachCurrentThread(); 276 JNIEnv* env = AttachCurrentThread();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 LOG(WARNING) << "Unexpected JS dialog cancel. " << id; 384 LOG(WARNING) << "Unexpected JS dialog cancel. " << id;
371 return; 385 return;
372 } 386 }
373 callback->Run(false, base::string16()); 387 callback->Run(false, base::string16());
374 pending_js_dialog_callbacks_.Remove(id); 388 pending_js_dialog_callbacks_.Remove(id);
375 } 389 }
376 390
377 // Use to cleanup if there is an error in client certificate response. 391 // Use to cleanup if there is an error in client certificate response.
378 void AwContentsClientBridge::HandleErrorInClientCertificateResponse( 392 void AwContentsClientBridge::HandleErrorInClientCertificateResponse(
379 int request_id) { 393 int request_id) {
380 SelectCertificateCallback* callback = 394 content::ClientCertificateDelegate* delegate =
381 pending_client_cert_request_callbacks_.Lookup(request_id); 395 pending_client_cert_request_delegates_.Lookup(request_id);
382 callback->Run(nullptr); 396 pending_client_cert_request_delegates_.Remove(request_id);
383 pending_client_cert_request_callbacks_.Remove(request_id); 397
398 delete delegate;
384 } 399 }
385 400
386 bool RegisterAwContentsClientBridge(JNIEnv* env) { 401 bool RegisterAwContentsClientBridge(JNIEnv* env) {
387 return RegisterNativesImpl(env); 402 return RegisterNativesImpl(env);
388 } 403 }
389 404
390 } // namespace android_webview 405 } // namespace android_webview
OLDNEW
« no previous file with comments | « android_webview/native/aw_contents_client_bridge.h ('k') | android_webview/native/aw_contents_client_bridge_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698