summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authordavidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-21 19:34:49 +0000
committerdavidben@chromium.org <davidben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-21 19:34:49 +0000
commit1f18184a07252103a8cd9652d64de749f41ef09f (patch)
tree7e0c5eb9dea2890d8231eb7ad69dec318ac6e610 /chrome
parent348b9bc12d4e2ccd03a7fbcb327a3975207a5fec (diff)
downloadchromium_src-1f18184a07252103a8cd9652d64de749f41ef09f.zip
chromium_src-1f18184a07252103a8cd9652d64de749f41ef09f.tar.gz
chromium_src-1f18184a07252103a8cd9652d64de749f41ef09f.tar.bz2
Refactor SSLClientAuthHandler and certificate selection
This cleans up much of the code involved in displaying a certificate selection dialog to the user. - Adds a new inner class to RenderViewHostDelegate (later to be populated with more SSL things). - Adds a helper class for TabContents' implementation. - Moves the certificate dialogs themselves to have a common entry point. - Makes SSLClientAuthHandler call the RVHDelegate to query the user, with the TabContents implementation displaying the dialogs. - Picks the correct parent window for the dialog on all platforms, instead of relying on BrowserList::GetLastActive - Makes the OS X implementation use an asynchronous sheet, now that we know the parent. - Fixes an index-mismatch problem in the OS X implementation, should we fail to create an identity. R=agl,brettw,mark BUG=148 TEST=selecting client certificates still works Review URL: http://codereview.chromium.org/2823038 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@53231 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/cocoa/ssl_client_certificate_selector.mm145
-rw-r--r--chrome/browser/gtk/ssl_client_certificate_selector.cc (renamed from chrome/browser/ssl/ssl_client_auth_handler_gtk.cc)19
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.cc5
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h14
-rw-r--r--chrome/browser/renderer_host/render_view_host_notification_task.h54
-rw-r--r--chrome/browser/ssl/ssl_client_auth_handler.cc50
-rw-r--r--chrome/browser/ssl/ssl_client_auth_handler.h14
-rw-r--r--chrome/browser/ssl/ssl_client_auth_handler_mac.mm63
-rw-r--r--chrome/browser/ssl_client_certificate_selector.h30
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc11
-rw-r--r--chrome/browser/tab_contents/tab_contents.h8
-rw-r--r--chrome/browser/tab_contents/tab_contents_ssl_helper.cc24
-rw-r--r--chrome/browser/tab_contents/tab_contents_ssl_helper.h28
-rw-r--r--chrome/browser/views/ssl_client_certificate_selector_win.cc (renamed from chrome/browser/ssl/ssl_client_auth_handler_win.cc)27
-rw-r--r--chrome/chrome_browser.gypi10
15 files changed, 392 insertions, 110 deletions
diff --git a/chrome/browser/cocoa/ssl_client_certificate_selector.mm b/chrome/browser/cocoa/ssl_client_certificate_selector.mm
new file mode 100644
index 0000000..3f057af
--- /dev/null
+++ b/chrome/browser/cocoa/ssl_client_certificate_selector.mm
@@ -0,0 +1,145 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ssl_client_certificate_selector.h"
+
+#import <SecurityInterface/SFChooseIdentityPanel.h>
+
+#include <vector>
+
+#import "app/l10n_util_mac.h"
+#include "base/logging.h"
+#include "base/ref_counted.h"
+#include "base/scoped_cftyperef.h"
+#import "base/scoped_nsobject.h"
+#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/ssl/ssl_client_auth_handler.h"
+#include "grit/generated_resources.h"
+#include "net/base/x509_certificate.h"
+
+@interface SSLClientCertificateSelectorCocoa : NSObject {
+ @private
+ // The handler to report back to.
+ scoped_refptr<SSLClientAuthHandler> handler_;
+ // The certificate request we serve.
+ scoped_refptr<net::SSLCertRequestInfo> certRequestInfo_;
+ // The list of identities offered to the user.
+ scoped_nsobject<NSMutableArray> identities_;
+ // The corresponding list of certificates.
+ std::vector<scoped_refptr<net::X509Certificate> > certificates_;
+ // The panel we display.
+ scoped_nsobject<SFChooseIdentityPanel> panel_;
+}
+
+- (id)initWithHandler:(SSLClientAuthHandler*)handler
+ certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo;
+- (void)displayDialog:(gfx::NativeWindow)parent;
+@end
+
+namespace browser {
+
+void ShowSSLClientCertificateSelector(
+ gfx::NativeWindow parent,
+ net::SSLCertRequestInfo* cert_request_info,
+ SSLClientAuthHandler* delegate) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ SSLClientCertificateSelectorCocoa* selector =
+ [[[SSLClientCertificateSelectorCocoa alloc]
+ initWithHandler:delegate
+ certRequestInfo:cert_request_info] autorelease];
+ [selector displayDialog:parent];
+}
+
+} // namespace browser
+
+@implementation SSLClientCertificateSelectorCocoa
+
+- (id)initWithHandler:(SSLClientAuthHandler*)handler
+ certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo {
+ DCHECK(handler);
+ DCHECK(certRequestInfo);
+ if ((self = [super init])) {
+ handler_ = handler;
+ certRequestInfo_ = certRequestInfo;
+ }
+ return self;
+}
+
+- (void)sheetDidEnd:(NSWindow*)parent
+ returnCode:(NSInteger)returnCode
+ context:(void*)context {
+ net::X509Certificate* cert = NULL;
+
+ if (returnCode == NSFileHandlingPanelOKButton) {
+ NSUInteger index = [identities_ indexOfObject:(id)[panel_ identity]];
+ DCHECK(index != NSNotFound);
+ cert = certificates_[index];
+ }
+
+ // Finally, tell the backend which identity (or none) the user selected.
+ handler_->CertificateSelected(cert);
+ // Clean up. The retain occurred just before the sheet opened.
+ [self release];
+}
+
+- (void)displayDialog:(gfx::NativeWindow)parent {
+ DCHECK(!panel_.get());
+ // Create an array of CFIdentityRefs for the certificates:
+ size_t numCerts = certRequestInfo_->client_certs.size();
+ identities_.reset([[NSMutableArray alloc] initWithCapacity:numCerts]);
+ for (size_t i = 0; i < numCerts; ++i) {
+ SecCertificateRef cert;
+ cert = certRequestInfo_->client_certs[i]->os_cert_handle();
+ SecIdentityRef identity;
+ if (SecIdentityCreateWithCertificate(NULL, cert, &identity) == noErr) {
+ [identities_ addObject:(id)identity];
+ CFRelease(identity);
+ certificates_.push_back(certRequestInfo_->client_certs[i]);
+ }
+ }
+
+ // Get the message to display:
+ NSString* title = l10n_util::GetNSString(IDS_CLIENT_CERT_DIALOG_TITLE);
+ NSString* message = l10n_util::GetNSStringF(
+ IDS_CLIENT_CERT_DIALOG_TEXT,
+ ASCIIToUTF16(certRequestInfo_->host_and_port));
+
+ // Create and set up a system choose-identity panel.
+ panel_.reset([[SFChooseIdentityPanel alloc] init]);
+ NSString* domain = base::SysUTF8ToNSString(
+ "https://" + certRequestInfo_->host_and_port);
+ // Setting the domain causes the dialog to record the preferred
+ // identity in the system keychain.
+ [panel_ setDomain:domain];
+ [panel_ setInformativeText:message];
+ [panel_ setDefaultButtonTitle:l10n_util::GetNSString(IDS_OK)];
+ [panel_ setAlternateButtonTitle:l10n_util::GetNSString(IDS_CANCEL)];
+ SecPolicyRef sslPolicy;
+ if (net::X509Certificate::CreateSSLClientPolicy(&sslPolicy) == noErr) {
+ [panel_ setPolicies:(id)sslPolicy];
+ CFRelease(sslPolicy);
+ }
+
+ // Increase the retain count to keep |self| alive while the sheet
+ // runs. -sheetDidEnd:returnCode:context: will release the
+ // additional reference.
+ [self retain];
+ if (parent) {
+ // Open the cert panel as a sheet on the browser window.
+ [panel_ beginSheetForWindow:parent
+ modalDelegate:self
+ didEndSelector:@selector(sheetDidEnd:returnCode:context:)
+ contextInfo:nil
+ identities:identities_
+ message:title];
+ } else {
+ // No available browser window, so run independently as a (blocking) dialog.
+ int returnCode = [panel_ runModalForIdentities:identities_ message:title];
+ [self sheetDidEnd:panel_ returnCode:returnCode context:nil];
+ }
+}
+
+@end
diff --git a/chrome/browser/ssl/ssl_client_auth_handler_gtk.cc b/chrome/browser/gtk/ssl_client_certificate_selector.cc
index 1045ef9..b7c3f5f 100644
--- a/chrome/browser/ssl/ssl_client_auth_handler_gtk.cc
+++ b/chrome/browser/gtk/ssl_client_certificate_selector.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/ssl/ssl_client_auth_handler.h"
+#include "chrome/browser/ssl_client_certificate_selector.h"
#include <cert.h>
#include <gtk/gtk.h>
@@ -17,6 +17,7 @@
#include "base/utf_string_conversions.h"
#include "chrome/browser/certificate_viewer.h"
#include "chrome/browser/gtk/gtk_util.h"
+#include "chrome/browser/ssl/ssl_client_auth_handler.h"
#include "chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h"
#include "chrome/third_party/mozilla_security_manager/nsNSSCertificate.h"
#include "chrome/third_party/mozilla_security_manager/nsUsageArrayHelper.h"
@@ -59,7 +60,7 @@ class SSLClientCertificateSelector {
static void OnDestroy(GtkDialog* dialog,
SSLClientCertificateSelector* cert_selector);
- SSLClientAuthHandler* delegate_;
+ scoped_refptr<SSLClientAuthHandler> delegate_;
scoped_refptr<net::SSLCertRequestInfo> cert_request_info_;
std::vector<std::string> details_strings_;
@@ -324,7 +325,15 @@ void SSLClientCertificateSelector::OnDestroy(
///////////////////////////////////////////////////////////////////////////////
// SSLClientAuthHandler platform specific implementation:
-void SSLClientAuthHandler::DoSelectCertificate() {
- // TODO(mattm): Pipe parent gfx::NativeWindow param into here somehow.
- (new SSLClientCertificateSelector(NULL, cert_request_info_, this))->Show();
+namespace browser {
+
+void ShowSSLClientCertificateSelector(
+ gfx::NativeWindow parent,
+ net::SSLCertRequestInfo* cert_request_info,
+ SSLClientAuthHandler* delegate) {
+ (new SSLClientCertificateSelector(parent,
+ cert_request_info,
+ delegate))->Show();
}
+
+} // namespace browser
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.cc b/chrome/browser/renderer_host/render_view_host_delegate.cc
index 11f6168fc..1396368 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.cc
+++ b/chrome/browser/renderer_host/render_view_host_delegate.cc
@@ -68,6 +68,11 @@ RenderViewHostDelegate::GetBookmarkDragDelegate() {
return NULL;
}
+RenderViewHostDelegate::SSL*
+RenderViewHostDelegate::GetSSLDelegate() {
+ return NULL;
+}
+
AutomationResourceRoutingDelegate*
RenderViewHostDelegate::GetAutomationResourceRoutingDelegate() {
return NULL;
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index 36b7a93..5817176 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/ref_counted.h"
#include "base/string16.h"
#include "chrome/common/content_settings_types.h"
#include "chrome/common/translate_errors.h"
@@ -37,6 +38,7 @@ class RenderViewHost;
class ResourceRedirectDetails;
class ResourceRequestDetails;
class SkBitmap;
+class SSLClientAuthHandler;
class TabContents;
struct ThumbnailScore;
struct ViewHostMsg_DidPrintPage_Params;
@@ -493,6 +495,17 @@ class RenderViewHostDelegate {
virtual void OnDrop(const BookmarkDragData& data) = 0;
};
+ // SSL -----------------------------------------------------------------------
+ // Interface for UI and other RenderViewHost-specific interactions with SSL.
+
+ class SSL {
+ public:
+ // Displays a dialog to select client certificates from |request_info|,
+ // returning them to |handler|.
+ virtual void ShowClientCertificateRequestDialog(
+ scoped_refptr<SSLClientAuthHandler> handler) = 0;
+ };
+
// ---------------------------------------------------------------------------
// Returns the current delegate associated with a feature. May return NULL if
@@ -508,6 +521,7 @@ class RenderViewHostDelegate {
virtual Autocomplete* GetAutocompleteDelegate();
virtual AutoFill* GetAutoFillDelegate();
virtual BookmarkDrag* GetBookmarkDragDelegate();
+ virtual SSL* GetSSLDelegate();
// Return the delegate for registering RenderViewHosts for automation resource
// routing.
diff --git a/chrome/browser/renderer_host/render_view_host_notification_task.h b/chrome/browser/renderer_host/render_view_host_notification_task.h
index c1d732a..1266922 100644
--- a/chrome/browser/renderer_host/render_view_host_notification_task.h
+++ b/chrome/browser/renderer_host/render_view_host_notification_task.h
@@ -147,6 +147,32 @@ inline void CallRenderViewHostRendererManagementDelegateHelper(
params));
}
+// For proxying calls to RenderViewHostDelegate::SSL
+
+class RenderViewHostToSSLDelegate {
+ public:
+ typedef RenderViewHostDelegate::SSL MappedType;
+ static MappedType* Map(RenderViewHost* rvh) {
+ return rvh ? rvh->delegate()->GetSSLDelegate() : NULL;
+ }
+};
+
+template <typename Method, typename Params>
+inline void CallRenderViewHostSSLDelegateHelper(
+ int render_process_id,
+ int render_view_id,
+ Method method,
+ const Params& params) {
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ new RenderViewHostNotificationTask<
+ Method, Params, RenderViewHostToSSLDelegate>(
+ render_process_id,
+ render_view_id,
+ method,
+ params));
+}
+
} // namespace internal
// ----------------------------------------------------------------------------
@@ -310,5 +336,33 @@ inline void CallRenderViewHostRendererManagementDelegate(int render_process_id,
}
// ----------------------------------------------------------------------------
+// Proxy calls to the specified RenderViewHost's SSL delegate.
+
+template <typename Method, typename A>
+inline void CallRenderViewHostSSLDelegate(int render_process_id,
+ int render_view_id,
+ Method method,
+ const A& a) {
+ internal::CallRenderViewHostSSLDelegateHelper(
+ render_process_id,
+ render_view_id,
+ method,
+ MakeTuple(a));
+}
+
+template <typename Method, typename A, typename B>
+inline void CallRenderViewHostSSLDelegate(int render_process_id,
+ int render_view_id,
+ Method method,
+ const A& a,
+ const B& b) {
+ internal::CallRenderViewHostSSLDelegateHelper(
+ render_process_id,
+ render_view_id,
+ method,
+ MakeTuple(a, b));
+}
+
+// ----------------------------------------------------------------------------
#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_NOTIFICATION_TASK_H_
diff --git a/chrome/browser/ssl/ssl_client_auth_handler.cc b/chrome/browser/ssl/ssl_client_auth_handler.cc
index f46c6f3..74b25bf 100644
--- a/chrome/browser/ssl/ssl_client_auth_handler.cc
+++ b/chrome/browser/ssl/ssl_client_auth_handler.cc
@@ -4,13 +4,10 @@
#include "chrome/browser/ssl/ssl_client_auth_handler.h"
-#include "app/l10n_util.h"
-#include "base/string_util.h"
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_window.h"
#include "chrome/browser/chrome_thread.h"
-#include "grit/generated_resources.h"
+#include "chrome/browser/renderer_host/render_view_host_delegate.h"
+#include "chrome/browser/renderer_host/render_view_host_notification_task.h"
+#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "net/url_request/url_request.h"
SSLClientAuthHandler::SSLClientAuthHandler(
@@ -18,11 +15,11 @@ SSLClientAuthHandler::SSLClientAuthHandler(
net::SSLCertRequestInfo* cert_request_info)
: request_(request),
cert_request_info_(cert_request_info) {
- // Keep us alive until a cert is selected.
- AddRef();
}
SSLClientAuthHandler::~SSLClientAuthHandler() {
+ // If we were simply dropped, then act as if we selected no certificate.
+ DoCertificateSelected(NULL);
}
void SSLClientAuthHandler::OnRequestCancelled() {
@@ -30,14 +27,24 @@ void SSLClientAuthHandler::OnRequestCancelled() {
}
void SSLClientAuthHandler::SelectCertificate() {
- // Let's move the request to the UI thread.
- ChromeThread::PostTask(
- ChromeThread::UI, FROM_HERE,
- NewRunnableMethod(this, &SSLClientAuthHandler::DoSelectCertificate));
-}
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
-// Looking for DoSelectCertificate()?
-// It's implemented in a separate source file for each platform.
+ int render_process_host_id;
+ int render_view_host_id;
+ if (!ResourceDispatcherHost::RenderViewForRequest(request_,
+ &render_process_host_id,
+ &render_view_host_id))
+ NOTREACHED();
+
+ // If the RVH does not exist by the time this task gets run, then the task
+ // will be dropped and the scoped_refptr to SSLClientAuthHandler will go
+ // away, so we do not leak anything. The destructor takes care of ensuring
+ // the URLRequest always gets a response.
+ CallRenderViewHostSSLDelegate(
+ render_process_host_id, render_view_host_id,
+ &RenderViewHostDelegate::SSL::ShowClientCertificateRequestDialog,
+ scoped_refptr<SSLClientAuthHandler>(this));
+}
// Notify the IO thread that we have selected a cert.
void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) {
@@ -48,11 +55,12 @@ void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) {
}
void SSLClientAuthHandler::DoCertificateSelected(net::X509Certificate* cert) {
- // request_ could have been NULLed if the request was cancelled while the user
- // was choosing a cert.
- if (request_)
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ // request_ could have been NULLed if the request was cancelled while the
+ // user was choosing a cert, or because we have already responded to the
+ // certificate.
+ if (request_) {
request_->ContinueWithCertificate(cert);
-
- // We are done.
- Release();
+ request_ = NULL;
+ }
}
diff --git a/chrome/browser/ssl/ssl_client_auth_handler.h b/chrome/browser/ssl/ssl_client_auth_handler.h
index f63d4c9..05148d5 100644
--- a/chrome/browser/ssl/ssl_client_auth_handler.h
+++ b/chrome/browser/ssl/ssl_client_auth_handler.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/ref_counted.h"
+#include "chrome/browser/chrome_thread.h"
#include "net/base/ssl_cert_request_info.h"
namespace net {
@@ -19,7 +20,8 @@ class URLRequest;
// It is self-owned and deletes itself when the UI reports the user selection or
// when the URLRequest is cancelled.
class SSLClientAuthHandler
- : public base::RefCountedThreadSafe<SSLClientAuthHandler> {
+ : public base::RefCountedThreadSafe<SSLClientAuthHandler,
+ ChromeThread::DeleteOnIOThread> {
public:
SSLClientAuthHandler(URLRequest* request,
net::SSLCertRequestInfo* cert_request_info);
@@ -38,15 +40,15 @@ class SSLClientAuthHandler
// be long after DoSelectCertificate returns, if the UI is modeless/async.)
void CertificateSelected(net::X509Certificate* cert);
+ // Returns the SSLCertRequestInfo for this handler.
+ net::SSLCertRequestInfo* cert_request_info() { return cert_request_info_; }
+
private:
- friend class base::RefCountedThreadSafe<SSLClientAuthHandler>;
+ friend class ChromeThread;
+ friend class DeleteTask<SSLClientAuthHandler>;
~SSLClientAuthHandler();
- // Asks the user for a cert.
- // Called on the UI thread.
- void DoSelectCertificate();
-
// Notifies that the user has selected a cert.
// Called on the IO thread.
void DoCertificateSelected(net::X509Certificate* cert);
diff --git a/chrome/browser/ssl/ssl_client_auth_handler_mac.mm b/chrome/browser/ssl/ssl_client_auth_handler_mac.mm
deleted file mode 100644
index cde8acc..0000000
--- a/chrome/browser/ssl/ssl_client_auth_handler_mac.mm
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ssl/ssl_client_auth_handler.h"
-
-#import <SecurityInterface/SFChooseIdentityPanel.h>
-
-#include "app/l10n_util_mac.h"
-#include "base/scoped_cftyperef.h"
-#include "base/scoped_nsobject.h"
-#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
-#include "chrome/browser/chrome_thread.h"
-#include "grit/generated_resources.h"
-#include "net/base/x509_certificate.h"
-
-void SSLClientAuthHandler::DoSelectCertificate() {
- net::X509Certificate* cert = NULL;
- // Create an array of CFIdentityRefs for the certificates:
- size_t num_certs = cert_request_info_->client_certs.size();
- NSMutableArray* identities = [NSMutableArray arrayWithCapacity:num_certs];
- for (size_t i = 0; i < num_certs; ++i) {
- SecCertificateRef cert;
- cert = cert_request_info_->client_certs[i]->os_cert_handle();
- SecIdentityRef identity;
- if (SecIdentityCreateWithCertificate(NULL, cert, &identity) == noErr) {
- [identities addObject:(id)identity];
- CFRelease(identity);
- }
- }
-
- // Get the message to display:
- NSString* title = l10n_util::GetNSString(IDS_CLIENT_CERT_DIALOG_TITLE);
- NSString* message = l10n_util::GetNSStringF(
- IDS_CLIENT_CERT_DIALOG_TEXT,
- ASCIIToUTF16(cert_request_info_->host_and_port));
-
- // Create and set up a system choose-identity panel.
- scoped_nsobject<SFChooseIdentityPanel> panel (
- [[SFChooseIdentityPanel alloc] init]);
- NSString* domain = base::SysUTF8ToNSString(
- "https://" + cert_request_info_->host_and_port);
- [panel setDomain:domain];
- [panel setInformativeText:message];
- [panel setAlternateButtonTitle:l10n_util::GetNSString(IDS_CANCEL)];
- SecPolicyRef sslPolicy;
- if (net::X509Certificate::CreateSSLClientPolicy(&sslPolicy) == noErr) {
- [panel setPolicies:(id)sslPolicy];
- CFRelease(sslPolicy);
- }
-
- // Run the panel, modally.
- // TODO(snej): Change this into a sheet so it doesn't block the runloop!
- if ([panel runModalForIdentities:identities message:title] == NSOKButton) {
- NSUInteger index = [identities indexOfObject:(id)[panel identity]];
- DCHECK(index != NSNotFound);
- cert = cert_request_info_->client_certs[index];
- }
-
- // Finally, tell the back end which identity (or none) the user selected.
- CertificateSelected(cert);
-}
diff --git a/chrome/browser/ssl_client_certificate_selector.h b/chrome/browser/ssl_client_certificate_selector.h
new file mode 100644
index 0000000..8a12a70
--- /dev/null
+++ b/chrome/browser/ssl_client_certificate_selector.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SSL_CLIENT_CERTIFICATE_SELECTOR_H_
+#define CHROME_BROWSER_SSL_CLIENT_CERTIFICATE_SELECTOR_H_
+
+#include "gfx/native_widget_types.h"
+
+class SSLClientAuthHandler;
+
+namespace net {
+class SSLCertRequestInfo;
+}
+
+namespace browser {
+
+// Opens an SSL client certificate selection dialog under |parent|, offering
+// certificates from |cert_request_info|. When the user has made a selection,
+// the dialog will report back to |delegate|. |delegate| is notified when the
+// dialog closes in call cases; if the user cancels the dialog, we call with a
+// NULL certificate.
+void ShowSSLClientCertificateSelector(
+ gfx::NativeWindow parent,
+ net::SSLCertRequestInfo* cert_request_info,
+ SSLClientAuthHandler* delegate);
+
+} // namespace browser
+
+#endif // CHROME_BROWSER_SSL_CLIENT_CERTIFICATE_SELECTOR_H_
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 73b1b9f..e25fc44 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -71,6 +71,7 @@
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/provisional_load_details.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
+#include "chrome/browser/tab_contents/tab_contents_ssl_helper.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/browser/tab_contents/thumbnail_generator.h"
#include "chrome/browser/translate/page_translated_details.h"
@@ -501,6 +502,12 @@ PluginInstaller* TabContents::GetPluginInstaller() {
return plugin_installer_.get();
}
+TabContentsSSLHelper* TabContents::GetSSLHelper() {
+ if (ssl_helper_.get() == NULL)
+ ssl_helper_.reset(new TabContentsSSLHelper(this));
+ return ssl_helper_.get();
+}
+
RenderProcessHost* TabContents::GetRenderProcessHost() const {
return render_manager_.current_host()->process();
}
@@ -2177,6 +2184,10 @@ RenderViewHostDelegate::AutoFill* TabContents::GetAutoFillDelegate() {
return GetAutoFillManager();
}
+RenderViewHostDelegate::SSL* TabContents::GetSSLDelegate() {
+ return GetSSLHelper();
+}
+
AutomationResourceRoutingDelegate*
TabContents::GetAutomationResourceRoutingDelegate() {
return delegate();
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index 49016ae..8d14246 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -88,6 +88,7 @@ class SkBitmap;
class TabContents;
class TabContentsDelegate;
class TabContentsFactory;
+class TabContentsSSLHelper;
class TabContentsView;
class URLPattern;
class URLRequestContextGetter;
@@ -168,6 +169,9 @@ class TabContents : public PageNavigator,
// Returns the PluginInstaller, creating it if necessary.
PluginInstaller* GetPluginInstaller();
+ // Returns the TabContentsSSLHelper, creating if it necessary.
+ TabContentsSSLHelper* GetSSLHelper();
+
// Returns the SavePackage which manages the page saving job. May be NULL.
SavePackage* save_package() const { return save_package_.get(); }
@@ -893,6 +897,7 @@ class TabContents : public PageNavigator,
virtual RenderViewHostDelegate::FavIcon* GetFavIconDelegate();
virtual RenderViewHostDelegate::Autocomplete* GetAutocompleteDelegate();
virtual RenderViewHostDelegate::AutoFill* GetAutoFillDelegate();
+ virtual RenderViewHostDelegate::SSL* GetSSLDelegate();
virtual AutomationResourceRoutingDelegate*
GetAutomationResourceRoutingDelegate();
virtual TabContents* GetAsTabContents();
@@ -1067,6 +1072,9 @@ class TabContents : public PageNavigator,
// PluginInstaller, lazily created.
scoped_ptr<PluginInstaller> plugin_installer_;
+ // TabContentsSSLHelper, lazily created.
+ scoped_ptr<TabContentsSSLHelper> ssl_helper_;
+
// Handles drag and drop event forwarding to extensions.
BookmarkDrag* bookmark_drag_;
diff --git a/chrome/browser/tab_contents/tab_contents_ssl_helper.cc b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc
new file mode 100644
index 0000000..0f00d1e
--- /dev/null
+++ b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/tab_contents/tab_contents_ssl_helper.h"
+
+#include "chrome/browser/ssl/ssl_client_auth_handler.h"
+#include "chrome/browser/ssl_client_certificate_selector.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+
+TabContentsSSLHelper::TabContentsSSLHelper(TabContents* tab_contents)
+ : tab_contents_(tab_contents) {
+}
+
+TabContentsSSLHelper::~TabContentsSSLHelper() {
+}
+
+void TabContentsSSLHelper::ShowClientCertificateRequestDialog(
+ scoped_refptr<SSLClientAuthHandler> handler) {
+ // Display the native certificate request dialog for each platform.
+ browser::ShowSSLClientCertificateSelector(
+ tab_contents_->GetMessageBoxRootWindow(),
+ handler->cert_request_info(), handler);
+}
diff --git a/chrome/browser/tab_contents/tab_contents_ssl_helper.h b/chrome/browser/tab_contents/tab_contents_ssl_helper.h
new file mode 100644
index 0000000..bddb379
--- /dev/null
+++ b/chrome/browser/tab_contents/tab_contents_ssl_helper.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_TAB_CONTENTS_TAB_CONTENTS_SSL_HELPER_H_
+#define CHROME_BROWSER_TAB_CONTENTS_TAB_CONTENTS_SSL_HELPER_H_
+
+#include "chrome/browser/renderer_host/render_view_host_delegate.h"
+
+class SSLClientAuthHandler;
+class TabContents;
+
+class TabContentsSSLHelper : public RenderViewHostDelegate::SSL {
+ public:
+ explicit TabContentsSSLHelper(TabContents* tab_contents);
+ virtual ~TabContentsSSLHelper();
+
+ // RenderViewHostDelegate::SSL implementation:
+ virtual void ShowClientCertificateRequestDialog(
+ scoped_refptr<SSLClientAuthHandler> handler);
+
+ private:
+ TabContents* tab_contents_;
+
+ DISALLOW_COPY_AND_ASSIGN(TabContentsSSLHelper);
+};
+
+#endif // CHROME_BROWSER_TAB_CONTENTS_TAB_CONTENTS_SSL_HELPER_H_
diff --git a/chrome/browser/ssl/ssl_client_auth_handler_win.cc b/chrome/browser/views/ssl_client_certificate_selector_win.cc
index cbac1ae..cf5ad4f3 100644
--- a/chrome/browser/ssl/ssl_client_auth_handler_win.cc
+++ b/chrome/browser/views/ssl_client_certificate_selector_win.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/ssl/ssl_client_auth_handler.h"
+#include "chrome/browser/ssl_client_certificate_selector.h"
#include <cryptuiapi.h>
#pragma comment(lib, "cryptui.lib")
@@ -13,10 +13,16 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/ssl/ssl_client_auth_handler.h"
#include "grit/generated_resources.h"
#include "net/url_request/url_request.h"
-void SSLClientAuthHandler::DoSelectCertificate() {
+namespace browser {
+
+void ShowSSLClientCertificateSelector(
+ gfx::NativeWindow parent,
+ net::SSLCertRequestInfo* cert_request_info,
+ SSLClientAuthHandler* delegate) {
net::X509Certificate* cert = NULL;
// TODO(jcampan): replace this with our own cert selection dialog.
// CryptUIDlgSelectCertificateFromStore is blocking (but still processes
@@ -24,24 +30,19 @@ void SSLClientAuthHandler::DoSelectCertificate() {
HCERTSTORE client_certs = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL,
0, NULL);
BOOL ok;
- for (size_t i = 0; i < cert_request_info_->client_certs.size(); ++i) {
- PCCERT_CONTEXT cc = cert_request_info_->client_certs[i]->os_cert_handle();
+ for (size_t i = 0; i < cert_request_info->client_certs.size(); ++i) {
+ PCCERT_CONTEXT cc = cert_request_info->client_certs[i]->os_cert_handle();
ok = CertAddCertificateContextToStore(client_certs, cc,
CERT_STORE_ADD_ALWAYS, NULL);
DCHECK(ok);
}
- HWND browser_hwnd = NULL;
- Browser* browser = BrowserList::GetLastActive();
- if (browser)
- browser_hwnd = browser->window()->GetNativeHandle();
-
std::wstring title = l10n_util::GetString(IDS_CLIENT_CERT_DIALOG_TITLE);
std::wstring text = l10n_util::GetStringF(
IDS_CLIENT_CERT_DIALOG_TEXT,
- ASCIIToWide(cert_request_info_->host_and_port));
+ ASCIIToWide(cert_request_info->host_and_port));
PCCERT_CONTEXT cert_context = CryptUIDlgSelectCertificateFromStore(
- client_certs, browser_hwnd, title.c_str(), text.c_str(), 0, 0, NULL);
+ client_certs, parent, title.c_str(), text.c_str(), 0, 0, NULL);
if (cert_context) {
cert = net::X509Certificate::CreateFromHandle(
@@ -54,5 +55,7 @@ void SSLClientAuthHandler::DoSelectCertificate() {
ok = CertCloseStore(client_certs, CERT_CLOSE_STORE_CHECK_FLAG);
DCHECK(ok);
- CertificateSelected(cert);
+ delegate->CertificateSelected(cert);
}
+
+} // namespace browser
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index ffa9db3..57e2996 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -946,6 +946,7 @@
'browser/cocoa/side_tab_strip_view.mm',
'browser/cocoa/simple_content_exceptions_window_controller.h',
'browser/cocoa/simple_content_exceptions_window_controller.mm',
+ 'browser/cocoa/ssl_client_certificate_selector.mm',
'browser/cocoa/status_bubble_mac.h',
'browser/cocoa/status_bubble_mac.mm',
'browser/cocoa/status_icons/status_icon_mac.h',
@@ -1620,6 +1621,7 @@
'browser/gtk/sad_tab_gtk.h',
'browser/gtk/slide_animator_gtk.cc',
'browser/gtk/slide_animator_gtk.h',
+ 'browser/gtk/ssl_client_certificate_selector.cc',
'browser/gtk/status_bubble_gtk.cc',
'browser/gtk/status_bubble_gtk.h',
'browser/gtk/status_icons/status_icon_gtk.h',
@@ -2260,9 +2262,6 @@
'browser/ssl/ssl_cert_error_handler.cc',
'browser/ssl/ssl_cert_error_handler.h',
'browser/ssl/ssl_client_auth_handler.cc',
- 'browser/ssl/ssl_client_auth_handler_mac.mm',
- 'browser/ssl/ssl_client_auth_handler_win.cc',
- 'browser/ssl/ssl_client_auth_handler_gtk.cc',
'browser/ssl/ssl_client_auth_handler.h',
'browser/ssl/ssl_error_handler.cc',
'browser/ssl/ssl_error_handler.h',
@@ -2277,6 +2276,7 @@
'browser/ssl/ssl_policy_backend.cc',
'browser/ssl/ssl_policy_backend.h',
'browser/ssl/ssl_request_info.h',
+ 'browser/ssl_client_certificate_selector.h',
'browser/status_bubble.h',
'browser/status_icons/status_tray.cc',
'browser/status_icons/status_tray.h',
@@ -2405,6 +2405,8 @@
'browser/tab_contents/tab_contents.h',
'browser/tab_contents/tab_contents_delegate.cc',
'browser/tab_contents/tab_contents_delegate.h',
+ 'browser/tab_contents/tab_contents_ssl_helper.cc',
+ 'browser/tab_contents/tab_contents_ssl_helper.h',
'browser/tab_contents/tab_contents_view.cc',
'browser/tab_contents/tab_contents_view.h',
'browser/tab_contents/tab_contents_view_gtk.cc',
@@ -2728,6 +2730,7 @@
'browser/views/sad_tab_view.h',
'browser/views/select_file_dialog.cc',
'browser/views/shell_dialogs_win.cc',
+ 'browser/views/ssl_client_certificate_selector_win.cc',
'browser/views/status_bubble_views.cc',
'browser/views/status_bubble_views.h',
'browser/views/status_icons/status_icon_win.cc',
@@ -3458,6 +3461,7 @@
['include', '^browser/gtk/popup_blocked_animation_gtk.cc'],
['include', '^browser/gtk/repost_form_warning_gtk.cc'],
['include', '^browser/gtk/repost_form_warning_gtk.h'],
+ ['include', '^browser/gtk/ssl_client_certificate_selector.cc'],
['include', '^browser/gtk/tab_contents_drag_source.cc'],
['include', '^browser/gtk/tab_contents_drag_source.h'],
['include', '^browser/gtk/task_manager_gtk.cc'],