| Index: chrome/browser/ui/android/ssl_client_certificate_selector.cc
|
| diff --git a/chrome/browser/ui/android/ssl_client_certificate_selector.cc b/chrome/browser/ui/android/ssl_client_certificate_selector.cc
|
| index 7d91dc10c7f32e026fe187eb5760abed49f040c6..940d983c8c30a03dbe0bb6a18988e4e887117a2f 100644
|
| --- a/chrome/browser/ui/android/ssl_client_certificate_selector.cc
|
| +++ b/chrome/browser/ui/android/ssl_client_certificate_selector.cc
|
| @@ -2,19 +2,70 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include "base/logging.h"
|
| #include "chrome/browser/ssl/ssl_client_certificate_selector.h"
|
| +#include "chrome/browser/ui/android/ssl_client_certificate_request.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "net/base/ssl_cert_request_info.h"
|
|
|
| -#include "base/logging.h"
|
| +// On other platforms, the list of client certificates compatible with
|
| +// the SSLCertRequestInfo is built using system APIs that do not require
|
| +// user interaction. After this, ShowSSLClientCertificateSelector() is
|
| +// merely used to display a tab sub-window asking the user to select
|
| +// one of these certificates.
|
| +
|
| +// On Android, things are a bit different, because getting the list of
|
| +// compatible client certificates is only possible using an API that shows
|
| +// a system UI dialog. More precisely:
|
| +//
|
| +// - The application must call KeyChain.choosePrivateKeyAlias() and
|
| +// pass it the request parameters directly.
|
| +//
|
| +// - This API always launches a system activity (CertInstaller), that
|
| +// will display a list of compatible installed client certificates,
|
| +// if any, or prompt the user to install one manually otherwise.
|
| +//
|
| +// - Also, the first time this API is called, the CertInstaller will
|
| +// first prompt the user to enter the secure storage's password
|
| +// (which is the user's PIN code / password by default). This establishes
|
| +// a trust relationship between the KeyChain system application, and
|
| +// the application calling the API. It persists until the application
|
| +// is killed.
|
| +//
|
| +// - The client certificate selection result is sent back to the
|
| +// application through a UI thread callback. It only contains a
|
| +// string alias for the selected certificate, or 'null' to indicate
|
| +// that the user has canceled the selection, or couldn't unlock
|
| +// access to the secure storage.
|
| +//
|
| +// Note that:
|
| +//
|
| +// - There is no way, when the result if 'null', to know from the
|
| +// application if the user cancelled the request, or couldn't access
|
| +// the secure storage.
|
| +//
|
| +// - There is no way to cancel a request once it has started. Each call
|
| +// to KeyChain.choosePrivateKeyAlias() launches a new activity, which
|
| +// runs in a completely different process, and steals the focus from
|
| +// the browser.
|
|
|
| namespace chrome {
|
|
|
| -// Client Auth is not implemented on Android yet.
|
| +using browser::android::SSLClientCertificateRequest;
|
| +
|
| void ShowSSLClientCertificateSelector(
|
| content::WebContents* contents,
|
| const net::HttpNetworkSession* network_session,
|
| net::SSLCertRequestInfo* cert_request_info,
|
| - const base::Callback<void(net::X509Certificate*)>& callback) {
|
| - NOTIMPLEMENTED();
|
| + const chrome::SelectCertificateCallback& callback) {
|
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
| + // Create a new request, then try to start it.
|
| + scoped_refptr<SSLClientCertificateRequest> request(
|
| + new SSLClientCertificateRequest(cert_request_info, callback));
|
| + if (!request->Start()) {
|
| + LOG(ERROR) << "Could not start client certificate request!";
|
| + // Note: the destructor will call callback(NULL) automatically.
|
| + }
|
| }
|
|
|
| } // namespace chrome
|
|
|