diff options
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 21 | ||||
-rw-r--r-- | chrome/browser/renderer_host/x509_user_cert_resource_handler.cc | 14 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_add_cert_handler.cc | 69 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_add_cert_handler.h | 50 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_add_cert_handler_mac.mm | 88 |
5 files changed, 234 insertions, 8 deletions
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index b7c75e4..94f60a8 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -1332,10 +1332,23 @@ void ResourceMessageFilter::OnKeygen(uint32 key_size_index, const std::string& challenge_string, const GURL& url, std::string* signed_public_key) { - scoped_ptr<net::KeygenHandler> keygen_handler( - new net::KeygenHandler(key_size_index, - challenge_string)); - *signed_public_key = keygen_handler->GenKeyAndSignChallenge(); + // Map displayed strings indicating level of keysecurity in the <keygen> + // menu to the key size in bits. (See SSLKeyGeneratorChromium.cpp in WebCore.) + int key_size_in_bits; + switch (key_size_index) { + case 0: + key_size_in_bits = 2048; + break; + case 1: + key_size_in_bits = 1024; + break; + default: + DCHECK(false) << "Illegal key_size_index " << key_size_index; + *signed_public_key = std::string(); + return; + } + net::KeygenHandler keygen_handler(key_size_in_bits, challenge_string); + *signed_public_key = keygen_handler.GenKeyAndSignChallenge(); } void ResourceMessageFilter::OnTranslateText( diff --git a/chrome/browser/renderer_host/x509_user_cert_resource_handler.cc b/chrome/browser/renderer_host/x509_user_cert_resource_handler.cc index 0c200a9..3dcc8ee 100644 --- a/chrome/browser/renderer_host/x509_user_cert_resource_handler.cc +++ b/chrome/browser/renderer_host/x509_user_cert_resource_handler.cc @@ -10,9 +10,9 @@ #include "chrome/browser/download/download_file.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h" +#include "chrome/browser/ssl/ssl_add_cert_handler.h" #include "chrome/common/resource_response.h" #include "chrome/common/url_constants.h" -#include "net/base/cert_database.h" #include "net/base/io_buffer.h" #include "net/base/mime_sniffer.h" #include "net/base/mime_util.h" @@ -91,12 +91,18 @@ bool X509UserCertResourceHandler::OnResponseCompleted( int request_id, const URLRequestStatus& urs, const std::string& sec_info) { + if (urs.status() != URLRequestStatus::SUCCESS) + return false; + // TODO(gauravsh): Verify that 'request_id' was actually a keygen form post // and only then import the certificate. - scoped_ptr<net::CertDatabase> cert_db(new net::CertDatabase()); AssembleResource(); - - return cert_db->AddUserCert(resource_buffer_->data(), content_length_); + scoped_refptr<net::X509Certificate> cert = + net::X509Certificate::CreateFromBytes(resource_buffer_->data(), + content_length_); + // The handler will run the UI and delete itself when it's finished. + new SSLAddCertHandler(request_, cert); + return true; } void X509UserCertResourceHandler::OnRequestClosed() { diff --git a/chrome/browser/ssl/ssl_add_cert_handler.cc b/chrome/browser/ssl/ssl_add_cert_handler.cc new file mode 100644 index 0000000..8c75d7d --- /dev/null +++ b/chrome/browser/ssl/ssl_add_cert_handler.cc @@ -0,0 +1,69 @@ +// 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_add_cert_handler.h" + +#include "app/l10n_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 "chrome/common/platform_util.h" +#include "grit/generated_resources.h" +#include "net/base/cert_database.h" +#include "net/base/net_errors.h" +#include "net/base/x509_certificate.h" +#include "net/url_request/url_request.h" + +SSLAddCertHandler::SSLAddCertHandler(URLRequest* request, + net::X509Certificate* cert) + : cert_(cert) { + // Stay alive until the UI completes and Finished() is called. + AddRef(); + ChromeThread::PostTask( + ChromeThread::UI, FROM_HERE, + NewRunnableMethod(this, &SSLAddCertHandler::RunUI)); +} + +void SSLAddCertHandler::RunUI() { + int cert_error; + { + net::CertDatabase db; + cert_error = db.CheckUserCert(cert_); + } + if (cert_error != net::OK) { + // TODO(snej): Map cert_error to a more specific error message. + ShowError(l10n_util::GetStringUTF16(IDS_ADD_CERT_ERR_INVALID_CERT)); + Finished(false); + return; + } + AskToAddCert(); +} + +#if !defined(OS_MACOSX) +void SSLAddCertHandler::AskToAddCert() { + // TODO(snej): Someone should add Windows and GTK implementations with UI. + Finished(true); +} +#endif + +void SSLAddCertHandler::Finished(bool add_cert) { + if (add_cert) { + net::CertDatabase db; + int cert_error = db.AddUserCert(cert_); + if (cert_error != net::OK) { + // TODO(snej): Map cert_error to a more specific error message. + ShowError(l10n_util::GetStringUTF16(IDS_ADD_CERT_ERR_FAILED)); + } + } + Release(); +} + +void SSLAddCertHandler::ShowError(const string16& error) { + Browser* browser = BrowserList::GetLastActive(); + platform_util::SimpleErrorBox( + browser ? browser->window()->GetNativeHandle() : NULL, + l10n_util::GetStringUTF16(IDS_ADD_CERT_FAILURE_TITLE), + error); +} diff --git a/chrome/browser/ssl/ssl_add_cert_handler.h b/chrome/browser/ssl/ssl_add_cert_handler.h new file mode 100644 index 0000000..0680128 --- /dev/null +++ b/chrome/browser/ssl/ssl_add_cert_handler.h @@ -0,0 +1,50 @@ +// 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_SSL_ADD_CERT_HANDLER_H_ +#define CHROME_BROWSER_SSL_SSL_ADD_CERT_HANDLER_H_ + +#include "base/basictypes.h" +#include "base/ref_counted.h" +#include "base/string16.h" + +namespace net { +class X509Certificate; +} +class URLRequest; + +// This class handles adding a newly-generated client cert. It ensures there's a +// private key for the cert, displays the cert to the user, and adds it upon +// user approval. +// It is self-owned and deletes itself when finished. +class SSLAddCertHandler : public base::RefCountedThreadSafe<SSLAddCertHandler> { + public: + SSLAddCertHandler(URLRequest* request, net::X509Certificate* cert); + + net::X509Certificate* cert() { return cert_; } + + // The platform-specific code calls this when it's done, to clean up. + // If |addCert| is true, the cert will be added to the CertDatabase. + void Finished(bool add_cert); + + private: + friend class base::RefCountedThreadSafe<SSLAddCertHandler>; + + // Runs the user interface. Called on the UI thread. Calls AskToAddCert. + void RunUI(); + + // Platform-specific code that asks the user whether to add the cert. + // Called on the UI thread. + void AskToAddCert(); + + // Utility to display an error message in a dialog box. + void ShowError(const string16& error); + + // The cert to add. + scoped_refptr<net::X509Certificate> cert_; + + DISALLOW_COPY_AND_ASSIGN(SSLAddCertHandler); +}; + +#endif // CHROME_BROWSER_SSL_SSL_ADD_CERT_HANDLER_H_ diff --git a/chrome/browser/ssl/ssl_add_cert_handler_mac.mm b/chrome/browser/ssl/ssl_add_cert_handler_mac.mm new file mode 100644 index 0000000..75b8142 --- /dev/null +++ b/chrome/browser/ssl/ssl_add_cert_handler_mac.mm @@ -0,0 +1,88 @@ +// 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 "ssl_add_cert_handler.h" + +#include <SecurityInterface/SFCertificatePanel.h> +#include <SecurityInterface/SFCertificateView.h> + +#include "app/l10n_util_mac.h" +#include "base/scoped_nsobject.h" +#include "chrome/common/logging_chrome.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_window.h" +#include "grit/generated_resources.h" +#include "net/base/x509_certificate.h" + +@interface SSLAddCertHandlerCocoa : NSObject +{ + scoped_refptr<SSLAddCertHandler> handler_; +} + +- (id)initWithHandler:(SSLAddCertHandler*)handler; +- (void)askToAddCert; +@end + + +void SSLAddCertHandler::AskToAddCert() { + [[[SSLAddCertHandlerCocoa alloc] initWithHandler: this] askToAddCert]; + // The new object will release itself when the sheet ends. +} + + +// The actual implementation of the add-client-cert handler is an Obj-C class. +@implementation SSLAddCertHandlerCocoa + +- (id)initWithHandler:(SSLAddCertHandler*)handler { + DCHECK(handler && handler->cert()); + self = [super init]; + if (self) { + handler_ = handler; + } + return self; +} + +- (void)sheetDidEnd:(SFCertificatePanel*)panel + returnCode:(NSInteger)returnCode + context:(void*)context { + [panel orderOut:self]; + [panel autorelease]; + handler_->Finished(returnCode == NSOKButton); + [self release]; +} + +- (void)askToAddCert { + NSWindow* parentWindow = NULL; + Browser* browser = BrowserList::GetLastActive(); + // TODO(snej): Can I get the Browser that issued the request? + if (browser) { + parentWindow = browser->window()->GetNativeHandle(); + if ([parentWindow attachedSheet]) + parentWindow = nil; + } + + // Create the cert panel, which will be released in my -sheetDidEnd: method. + SFCertificatePanel* panel = [[SFCertificatePanel alloc] init]; + [panel setDefaultButtonTitle:l10n_util::GetNSString(IDS_ADD_CERT_DIALOG_ADD)]; + [panel setAlternateButtonTitle:l10n_util::GetNSString(IDS_CANCEL)]; + SecCertificateRef cert = handler_->cert()->os_cert_handle(); + NSArray* certs = [NSArray arrayWithObject: (id)cert]; + + if (parentWindow) { + // Open the cert panel as a sheet on the browser window. + [panel beginSheetForWindow:parentWindow + modalDelegate:self + didEndSelector:@selector(sheetDidEnd:returnCode:context:) + contextInfo:NULL + certificates:certs + showGroup:NO]; + } else { + // No available browser window, so run independently as a (blocking) dialog. + int returnCode = [panel runModalForCertificates:certs showGroup:NO]; + [self sheetDidEnd:panel returnCode:returnCode context:NULL]; + } +} + +@end |