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 |