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

Unified Diff: chrome/browser/cocoa/ssl_client_certificate_selector.mm

Issue 2823038: Refactor SSLClientAuthHandler and certificate selection (Closed)
Patch Set: Rebase the patch Created 10 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/gtk/ssl_client_certificate_selector.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/cocoa/ssl_client_certificate_selector.mm
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 0000000000000000000000000000000000000000..3f057aff6485a16371c3d261e3feb95b2d324785
--- /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
« no previous file with comments | « no previous file | chrome/browser/gtk/ssl_client_certificate_selector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698