OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/ssl/ssl_client_auth_handler.h" |
| 6 |
| 7 #if defined (OS_WIN) |
| 8 #include <cryptuiapi.h> |
| 9 #pragma comment(lib, "cryptui.lib") |
| 10 #endif |
| 11 |
| 12 #include "app/l10n_util.h" |
| 13 #include "base/message_loop.h" |
| 14 #include "base/string_util.h" |
| 15 #include "chrome/browser/browser_list.h" |
| 16 #include "chrome/browser/browser.h" |
| 17 #include "chrome/browser/browser_window.h" |
| 18 #include "grit/generated_resources.h" |
| 19 #include "net/url_request/url_request.h" |
| 20 |
| 21 SSLClientAuthHandler::SSLClientAuthHandler( |
| 22 URLRequest* request, |
| 23 net::SSLCertRequestInfo* cert_request_info, |
| 24 MessageLoop* io_loop, |
| 25 MessageLoop* ui_loop) |
| 26 : request_(request), |
| 27 cert_request_info_(cert_request_info), |
| 28 io_loop_(io_loop), |
| 29 ui_loop_(ui_loop) { |
| 30 // Keep us alive until a cert is selected. |
| 31 AddRef(); |
| 32 } |
| 33 |
| 34 SSLClientAuthHandler::~SSLClientAuthHandler() { |
| 35 } |
| 36 |
| 37 void SSLClientAuthHandler::OnRequestCancelled() { |
| 38 request_ = NULL; |
| 39 } |
| 40 |
| 41 void SSLClientAuthHandler::SelectCertificate() { |
| 42 // Let's move the request to the UI thread. |
| 43 ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, |
| 44 &SSLClientAuthHandler::AskUserForCertificate)); |
| 45 } |
| 46 |
| 47 void SSLClientAuthHandler::AskUserForCertificate() { |
| 48 net::X509Certificate* cert = NULL; |
| 49 #if defined(OS_WIN) |
| 50 // TODO(jcampan): replace this with our own cert selection dialog. |
| 51 // CryptUIDlgSelectCertificateFromStore is blocking (but still processes |
| 52 // Windows messages), which is scary. |
| 53 HCERTSTORE client_certs = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, |
| 54 0, NULL); |
| 55 BOOL ok; |
| 56 for (size_t i = 0; i < cert_request_info_->client_certs.size(); ++i) { |
| 57 PCCERT_CONTEXT cc = cert_request_info_->client_certs[i]->os_cert_handle(); |
| 58 ok = CertAddCertificateContextToStore(client_certs, cc, |
| 59 CERT_STORE_ADD_ALWAYS, NULL); |
| 60 DCHECK(ok); |
| 61 } |
| 62 |
| 63 HWND browser_hwnd = NULL; |
| 64 Browser* browser = BrowserList::GetLastActive(); |
| 65 if (browser) |
| 66 browser_hwnd = browser->window()->GetNativeHandle(); |
| 67 |
| 68 std::wstring title = l10n_util::GetString(IDS_CLIENT_CERT_DIALOG_TITLE); |
| 69 std::wstring text = l10n_util::GetStringF( |
| 70 IDS_CLIENT_CERT_DIALOG_TEXT, |
| 71 ASCIIToWide(cert_request_info_->host_and_port)); |
| 72 PCCERT_CONTEXT cert_context = CryptUIDlgSelectCertificateFromStore( |
| 73 client_certs, browser_hwnd, title.c_str(), text.c_str(), 0, 0, NULL); |
| 74 |
| 75 if (cert_context) { |
| 76 cert = net::X509Certificate::CreateFromHandle( |
| 77 cert_context, |
| 78 net::X509Certificate::SOURCE_LONE_CERT_IMPORT); |
| 79 } |
| 80 |
| 81 ok = CertCloseStore(client_certs, CERT_CLOSE_STORE_CHECK_FLAG); |
| 82 DCHECK(ok); |
| 83 #else |
| 84 NOTIMPLEMENTED(); |
| 85 #endif |
| 86 |
| 87 // Notify the IO thread that we have selected a cert. |
| 88 io_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, |
| 89 &SSLClientAuthHandler::CertificateSelected, cert)); |
| 90 } |
| 91 |
| 92 void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) { |
| 93 // request_ could have been NULLed if the request was cancelled while the user |
| 94 // was choosing a cert. |
| 95 if (request_) |
| 96 request_->ContinueWithCertificate(cert); |
| 97 |
| 98 // We are done. |
| 99 Release(); |
| 100 } |
OLD | NEW |