15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/ssl_client_certificate_selector.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/certificate_viewer.h"
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/ui/views/constrained_window_views.h"
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_certificate.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/table_model.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/table_model_observer.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/button/label_button.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/table/table_view.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/layout_constants.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/window/dialog_client_view.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(USE_NSS)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/crypto_module_password_dialog_nss.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CertificateSelectorTableModel:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CertificateSelectorTableModel : public ui::TableModel {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit CertificateSelectorTableModel(
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::SSLCertRequestInfo* cert_request_info);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ui::TableModel implementation:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int RowCount() OVERRIDE;
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual base::string16 GetText(int index, int column_id) OVERRIDE;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetObserver(ui::TableModelObserver* observer) OVERRIDE;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<base::string16> items_;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CertificateSelectorTableModel);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CertificateSelectorTableModel::CertificateSelectorTableModel(
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::SSLCertRequestInfo* cert_request_info) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < cert_request_info->client_certs.size(); ++i) {
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    net::X509Certificate* cert = cert_request_info->client_certs[i].get();
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 text = l10n_util::GetStringFUTF16(
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDS_CERT_SELECTOR_TABLE_CERT_FORMAT,
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::UTF8ToUTF16(cert->subject().GetDisplayName()),
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::UTF8ToUTF16(cert->issuer().GetDisplayName()));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    items_.push_back(text);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CertificateSelectorTableModel::RowCount() {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return items_.size();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 CertificateSelectorTableModel::GetText(int index,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                      int column_id) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(column_id, 0);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(index, 0);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(index, static_cast<int>(items_.size()));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return items_[index];
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CertificateSelectorTableModel::SetObserver(
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::TableModelObserver* observer) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SSLClientCertificateSelector:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientCertificateSelector::SSLClientCertificateSelector(
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    content::WebContents* web_contents,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HttpNetworkSession* network_session,
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const chrome::SelectCertificateCallback& callback)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SSLClientAuthObserver(network_session, cert_request_info, callback),
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      model_(new CertificateSelectorTableModel(cert_request_info.get())),
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_(web_contents),
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      table_(NULL),
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      view_cert_button_(NULL) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientCertificateSelector::~SSLClientCertificateSelector() {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  table_->SetModel(NULL);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientCertificateSelector::Init() {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::GridLayout* layout = views::GridLayout::CreatePanel(this);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetLayoutManager(layout);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int column_set_id = 0;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::ColumnSet* column_set = layout->AddColumnSet(column_set_id);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set->AddColumn(
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      views::GridLayout::FILL, views::GridLayout::FILL,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, views::GridLayout::USE_PREF, 0, 0);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->StartRow(0, column_set_id);
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 text = l10n_util::GetStringFUTF16(
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_CLIENT_CERT_DIALOG_TEXT,
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::ASCIIToUTF16(cert_request_info()->host_and_port.ToString()));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Label* label = new views::Label(text);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label->SetMultiLine(true);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label->SetAllowCharacterBreak(true);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(label);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The dimensions of the certificate selector table view, in pixels.
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  static const int kTableViewWidth = 400;
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  static const int kTableViewHeight = 100;
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateCertTable();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->StartRow(1, column_set_id);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(table_->CreateParentIfNecessary(), 1, 1,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  views::GridLayout::FILL,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  views::GridLayout::FILL, kTableViewWidth, kTableViewHeight);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartObserving();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ShowWebModalDialogViews(this, web_contents_);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Select the first row automatically.  This must be done after the dialog has
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // been created.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  table_->Select(0);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::X509Certificate* SSLClientCertificateSelector::GetSelectedCert() const {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int selected = table_->FirstSelectedRow();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selected >= 0 &&
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      selected < static_cast<int>(cert_request_info()->client_certs.size()))
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return cert_request_info()->client_certs[selected].get();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SSLClientAuthObserver implementation:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientCertificateSelector::OnCertSelectedByNotification() {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetWidget()->Close();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DialogDelegateView implementation:
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientCertificateSelector::CanResize() const {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 SSLClientCertificateSelector::GetWindowTitle() const {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientCertificateSelector::DeleteDelegate() {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientCertificateSelector::IsDialogButtonEnabled(
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::DialogButton button) const {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (button == ui::DIALOG_BUTTON_OK)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return !!GetSelectedCert();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientCertificateSelector::Cancel() {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopObserving();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertificateSelected(NULL);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SSLClientCertificateSelector::Accept() {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<net::X509Certificate> cert = GetSelectedCert();
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (cert.get()) {
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Remove the observer before we try unlocking, otherwise we might act on a
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // notification while waiting for the unlock dialog, causing us to delete
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // ourself before the Unlocked callback gets called.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopObserving();
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(USE_NSS)
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    chrome::UnlockCertSlotIfNecessary(
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        cert.get(),
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        chrome::kCryptoModulePasswordClientAuth,
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        cert_request_info()->host_and_port,
20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        GetWidget()->GetNativeView(),
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&SSLClientCertificateSelector::Unlocked,
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   base::Unretained(this),
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   cert));
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Unlocked(cert.get());
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;  // Unlocked() will close the dialog.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* SSLClientCertificateSelector::GetInitiallyFocusedView() {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return table_;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)views::View* SSLClientCertificateSelector::CreateExtraView() {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!view_cert_button_);
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  view_cert_button_ = new views::LabelButton(this,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON));
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  view_cert_button_->SetStyle(views::Button::STYLE_BUTTON);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return view_cert_button_;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::ModalType SSLClientCertificateSelector::GetModalType() const {
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ui::MODAL_TYPE_CHILD;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// views::ButtonListener implementation:
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientCertificateSelector::ButtonPressed(
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::Button* sender, const ui::Event& event) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sender == view_cert_button_) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::X509Certificate* cert = GetSelectedCert();
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cert)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ShowCertificateViewer(web_contents_,
240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                            web_contents_->GetTopLevelNativeWindow(),
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            cert);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// views::TableViewObserver implementation:
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientCertificateSelector::OnSelectionChanged() {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetDialogClientView()->ok_button()->SetEnabled(!!GetSelectedCert());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientCertificateSelector::OnDoubleClick() {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (Accept())
25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    GetWidget()->Close();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SSLClientCertificateSelector private methods:
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientCertificateSelector::CreateCertTable() {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ui::TableColumn> columns;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns.push_back(ui::TableColumn());
26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  table_ = new views::TableView(model_.get(), columns, views::TEXT_ONLY,
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                true /* single_selection */);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  table_->SetObserver(this);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SSLClientCertificateSelector::Unlocked(net::X509Certificate* cert) {
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CertificateSelected(cert);
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetWidget()->Close();
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowSSLClientCertificateSelector(
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WebContents* contents,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HttpNetworkSession* network_session,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::SSLCertRequestInfo* cert_request_info,
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const chrome::SelectCertificateCallback& callback) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " " << contents;
28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (new SSLClientCertificateSelector(
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       contents, network_session, cert_request_info, callback))->Init();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
287