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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java

Issue 1327103003: Handle ActivityNotFoundException when selecting client cert (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated string descriptions Created 5 years, 3 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
« no previous file with comments | « no previous file | chrome/android/java/strings/android_chrome_strings.grd » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 package org.chromium.chrome.browser; 5 package org.chromium.chrome.browser;
6 6
7 import android.app.Activity; 7 import android.app.Activity;
8 import android.content.ActivityNotFoundException;
8 import android.content.Context; 9 import android.content.Context;
10 import android.content.DialogInterface;
11 import android.content.DialogInterface.OnClickListener;
9 import android.os.AsyncTask; 12 import android.os.AsyncTask;
10 import android.security.KeyChain; 13 import android.security.KeyChain;
11 import android.security.KeyChainAliasCallback; 14 import android.security.KeyChainAliasCallback;
12 import android.security.KeyChainException; 15 import android.security.KeyChainException;
16 import android.support.v7.app.AlertDialog;
13 import android.util.Log; 17 import android.util.Log;
14 18
15 import org.chromium.base.ThreadUtils; 19 import org.chromium.base.ThreadUtils;
20 import org.chromium.base.VisibleForTesting;
16 import org.chromium.base.annotations.CalledByNative; 21 import org.chromium.base.annotations.CalledByNative;
17 import org.chromium.base.annotations.JNINamespace; 22 import org.chromium.base.annotations.JNINamespace;
23 import org.chromium.chrome.R;
18 import org.chromium.chrome.browser.smartcard.PKCS11AuthenticationManager; 24 import org.chromium.chrome.browser.smartcard.PKCS11AuthenticationManager;
19 import org.chromium.net.AndroidPrivateKey; 25 import org.chromium.net.AndroidPrivateKey;
20 import org.chromium.net.DefaultAndroidKeyStore; 26 import org.chromium.net.DefaultAndroidKeyStore;
21 import org.chromium.ui.base.WindowAndroid; 27 import org.chromium.ui.base.WindowAndroid;
22 28
23 import java.security.Principal; 29 import java.security.Principal;
24 import java.security.cert.CertificateEncodingException; 30 import java.security.cert.CertificateEncodingException;
25 import java.security.cert.X509Certificate; 31 import java.security.cert.X509Certificate;
26 32
27 import javax.security.auth.x500.X500Principal; 33 import javax.security.auth.x500.X500Principal;
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 }); 212 });
207 } else { 213 } else {
208 new CertAsyncTaskKeyChain(mContext, mNativePtr, alias).e xecute(); 214 new CertAsyncTaskKeyChain(mContext, mNativePtr, alias).e xecute();
209 } 215 }
210 } 216 }
211 }); 217 });
212 } 218 }
213 } 219 }
214 220
215 /** 221 /**
222 * Wrapper class for the static KeyChain#choosePrivateKeyAlias method to fac ilitate testing.
223 */
224 @VisibleForTesting
225 static class KeyChainCertSelectionWrapper {
226 private final Activity mActivity;
227 private final KeyChainAliasCallback mCallback;
228 private final String[] mKeyTypes;
229 private final Principal[] mPrincipalsForCallback;
230 private final String mHostName;
231 private final int mPort;
232 private final String mAlias;
233
234 public KeyChainCertSelectionWrapper(Activity activity, KeyChainAliasCall back callback,
235 String[] keyTypes, Principal[] principalsForCallback, String hos tName, int port,
236 String alias) {
237 mActivity = activity;
238 mCallback = callback;
239 mKeyTypes = keyTypes;
240 mPrincipalsForCallback = principalsForCallback;
241 mHostName = hostName;
242 mPort = port;
243 mAlias = alias;
244 }
245
246 /**
247 * Calls KeyChain#choosePrivateKeyAlias with the provided arguments.
248 */
249 public void choosePrivateKeyAlias() throws ActivityNotFoundException {
250 KeyChain.choosePrivateKeyAlias(mActivity, mCallback, mKeyTypes, mPri ncipalsForCallback,
251 mHostName, mPort, mAlias);
252 }
253 }
254
255 /**
256 * Dialog that explains to the user that client certificates aren't supporte d on their operating
257 * system. Separated out into its own class to allow Robolectric unit testin g of
258 * maybeShowCertSelection without depending on Chrome resources.
259 */
260 @VisibleForTesting
261 static class CertSelectionFailureDialog {
262 private final Activity mActivity;
263
264 public CertSelectionFailureDialog(Activity activity) {
265 mActivity = activity;
266 }
267
268 /**
269 * Builds and shows the dialog.
270 */
271 public void show() {
272 final AlertDialog.Builder builder =
273 new AlertDialog.Builder(mActivity, R.style.AlertDialogTheme) ;
274 builder.setTitle(R.string.client_cert_unsupported_title)
275 .setMessage(R.string.client_cert_unsupported_message)
276 .setNegativeButton(R.string.close,
277 new OnClickListener() {
278 public void onClick(DialogInterface dialog, int which) {
279 // Do nothing
280 }
281 });
282 builder.show();
283 }
284 }
285
286 /**
216 * Create a new asynchronous request to select a client certificate. 287 * Create a new asynchronous request to select a client certificate.
217 * 288 *
218 * @param nativePtr The native object responsible for this request. 289 * @param nativePtr The native object responsible for this request.
219 * @param window A WindowAndroid instance. 290 * @param window A WindowAndroid instance.
220 * @param keyTypes The list of supported key exchange types. 291 * @param keyTypes The list of supported key exchange types.
221 * @param encodedPrincipals The list of CA DistinguishedNames. 292 * @param encodedPrincipals The list of CA DistinguishedNames.
222 * @param hostName The server host name is available (empty otherwi se). 293 * @param hostName The server host name is available (empty otherwi se).
223 * @param port The server port if available (0 otherwise). 294 * @param port The server port if available (0 otherwise).
224 * @return true on success. 295 * @return true on success.
225 * Note that nativeOnSystemRequestComplete will be called iff this method re turns true. 296 * Note that nativeOnSystemRequestComplete will be called iff this method re turns true.
(...skipping 26 matching lines...) Expand all
252 323
253 final Principal[] principalsForCallback = principals; 324 final Principal[] principalsForCallback = principals;
254 // Certificate for client authentication can be obtained either from the system store of 325 // Certificate for client authentication can be obtained either from the system store of
255 // from a smart card (if available). 326 // from a smart card (if available).
256 Runnable useSystemStore = new Runnable() { 327 Runnable useSystemStore = new Runnable() {
257 @Override 328 @Override
258 public void run() { 329 public void run() {
259 KeyChainCertSelectionCallback callback = 330 KeyChainCertSelectionCallback callback =
260 new KeyChainCertSelectionCallback(activity.getApplicatio nContext(), 331 new KeyChainCertSelectionCallback(activity.getApplicatio nContext(),
261 nativePtr); 332 nativePtr);
262 KeyChain.choosePrivateKeyAlias(activity, callback, keyTypes, pri ncipalsForCallback, 333 KeyChainCertSelectionWrapper keyChain = new KeyChainCertSelectio nWrapper(activity,
263 hostName, port, null); 334 callback, keyTypes, principalsForCallback, hostName, por t, null);
335 maybeShowCertSelection(keyChain, callback,
336 new CertSelectionFailureDialog(activity));
264 } 337 }
265 }; 338 };
266 339
267 final Context appContext = activity.getApplicationContext(); 340 final Context appContext = activity.getApplicationContext();
268 final PKCS11AuthenticationManager smartCardAuthManager = 341 final PKCS11AuthenticationManager smartCardAuthManager =
269 ((ChromeApplication) appContext).getPKCS11AuthenticationManager( ); 342 ((ChromeApplication) appContext).getPKCS11AuthenticationManager( );
270 if (smartCardAuthManager.isPKCS11AuthEnabled()) { 343 if (smartCardAuthManager.isPKCS11AuthEnabled()) {
271 // Smart card support is available, prompt the user whether to use i t or Android system 344 // Smart card support is available, prompt the user whether to use i t or Android system
272 // store. 345 // store.
273 Runnable useSmartCard = new Runnable() { 346 Runnable useSmartCard = new Runnable() {
(...skipping 16 matching lines...) Expand all
290 selectionDialog.show(activity.getFragmentManager(), null); 363 selectionDialog.show(activity.getFragmentManager(), null);
291 } else { 364 } else {
292 // Smart card support is not available, use the system store uncondi tionally. 365 // Smart card support is not available, use the system store uncondi tionally.
293 useSystemStore.run(); 366 useSystemStore.run();
294 } 367 }
295 368
296 // We've taken ownership of the native ssl request object. 369 // We've taken ownership of the native ssl request object.
297 return true; 370 return true;
298 } 371 }
299 372
373 /**
374 * Attempt to show the certificate selection dialog and shows the provided
375 * CertSelectionFailureDialog if the platform's cert selection activity can' t be found.
376 */
377 @VisibleForTesting
378 static void maybeShowCertSelection(KeyChainCertSelectionWrapper keyChain,
379 KeyChainAliasCallback callback, CertSelectionFailureDialog failureDi alog) {
380 try {
381 keyChain.choosePrivateKeyAlias();
382 } catch (ActivityNotFoundException e) {
383 // This exception can be hit when a platform is missing the activity to select
384 // a client certificate. It gets handled here to avoid a crash.
385 // Complete the callback without selecting a certificate.
386 callback.alias(null);
387 // Show a dialog letting the user know that the system does not supp ort
388 // client certificate selection.
389 failureDialog.show();
390 }
391 }
392
300 public static void notifyClientCertificatesChangedOnIOThread() { 393 public static void notifyClientCertificatesChangedOnIOThread() {
301 Log.d(TAG, "ClientCertificatesChanged!"); 394 Log.d(TAG, "ClientCertificatesChanged!");
302 nativeNotifyClientCertificatesChangedOnIOThread(); 395 nativeNotifyClientCertificatesChangedOnIOThread();
303 } 396 }
304 397
305 private static native void nativeNotifyClientCertificatesChangedOnIOThread() ; 398 private static native void nativeNotifyClientCertificatesChangedOnIOThread() ;
306 399
307 // Called to pass request results to native side. 400 // Called to pass request results to native side.
308 private static native void nativeOnSystemRequestCompletion( 401 private static native void nativeOnSystemRequestCompletion(
309 long requestPtr, byte[][] certChain, AndroidPrivateKey androidKey); 402 long requestPtr, byte[][] certChain, AndroidPrivateKey androidKey);
310 } 403 }
OLDNEW
« no previous file with comments | « no previous file | chrome/android/java/strings/android_chrome_strings.grd » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698