OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/certificate_selector.h" | 5 #include "chrome/browser/ui/views/certificate_selector.h" |
6 | 6 |
7 #include <stddef.h> // For size_t. | 7 #include <stddef.h> // For size_t. |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 27 matching lines...) Expand all Loading... |
38 #include "extensions/browser/extension_registry_factory.h" | 38 #include "extensions/browser/extension_registry_factory.h" |
39 #endif | 39 #endif |
40 | 40 |
41 namespace chrome { | 41 namespace chrome { |
42 | 42 |
43 const int CertificateSelector::kTableViewWidth = 500; | 43 const int CertificateSelector::kTableViewWidth = 500; |
44 const int CertificateSelector::kTableViewHeight = 150; | 44 const int CertificateSelector::kTableViewHeight = 150; |
45 | 45 |
46 class CertificateSelector::CertificateTableModel : public ui::TableModel { | 46 class CertificateSelector::CertificateTableModel : public ui::TableModel { |
47 public: | 47 public: |
48 // |certs| and |provider_names| must have the same size. | 48 // |identities| and |provider_names| must have the same size. |
49 CertificateTableModel(const net::CertificateList& certs, | 49 CertificateTableModel(const net::ClientCertIdentityList& identities, |
50 const std::vector<std::string>& provider_names); | 50 const std::vector<std::string>& provider_names); |
51 | 51 |
52 // ui::TableModel: | 52 // ui::TableModel: |
53 int RowCount() override; | 53 int RowCount() override; |
54 base::string16 GetText(int index, int column_id) override; | 54 base::string16 GetText(int index, int column_id) override; |
55 void SetObserver(ui::TableModelObserver* observer) override; | 55 void SetObserver(ui::TableModelObserver* observer) override; |
56 | 56 |
57 private: | 57 private: |
58 struct Row { | 58 struct Row { |
59 base::string16 subject; | 59 base::string16 subject; |
60 base::string16 issuer; | 60 base::string16 issuer; |
61 base::string16 provider; | 61 base::string16 provider; |
62 base::string16 serial; | 62 base::string16 serial; |
63 }; | 63 }; |
64 std::vector<Row> rows_; | 64 std::vector<Row> rows_; |
65 | 65 |
66 DISALLOW_COPY_AND_ASSIGN(CertificateTableModel); | 66 DISALLOW_COPY_AND_ASSIGN(CertificateTableModel); |
67 }; | 67 }; |
68 | 68 |
69 CertificateSelector::CertificateTableModel::CertificateTableModel( | 69 CertificateSelector::CertificateTableModel::CertificateTableModel( |
70 const net::CertificateList& certs, | 70 const net::ClientCertIdentityList& identities, |
71 const std::vector<std::string>& provider_names) { | 71 const std::vector<std::string>& provider_names) { |
72 DCHECK_EQ(certs.size(), provider_names.size()); | 72 DCHECK_EQ(identities.size(), provider_names.size()); |
73 for (size_t i = 0; i < certs.size(); i++) { | 73 for (size_t i = 0; i < identities.size(); i++) { |
74 net::X509Certificate* cert = certs[i].get(); | 74 net::X509Certificate* cert = identities[i]->certificate(); |
75 Row row; | 75 Row row; |
76 row.subject = base::UTF8ToUTF16(cert->subject().GetDisplayName()); | 76 row.subject = base::UTF8ToUTF16(cert->subject().GetDisplayName()); |
77 row.issuer = base::UTF8ToUTF16(cert->issuer().GetDisplayName()); | 77 row.issuer = base::UTF8ToUTF16(cert->issuer().GetDisplayName()); |
78 row.provider = base::UTF8ToUTF16(provider_names[i]); | 78 row.provider = base::UTF8ToUTF16(provider_names[i]); |
79 if (cert->serial_number().size() < std::numeric_limits<size_t>::max() / 2) { | 79 if (cert->serial_number().size() < std::numeric_limits<size_t>::max() / 2) { |
80 row.serial = base::UTF8ToUTF16(base::HexEncode( | 80 row.serial = base::UTF8ToUTF16(base::HexEncode( |
81 cert->serial_number().data(), cert->serial_number().size())); | 81 cert->serial_number().data(), cert->serial_number().size())); |
82 } | 82 } |
83 rows_.push_back(row); | 83 rows_.push_back(row); |
84 } | 84 } |
(...skipping 21 matching lines...) Expand all Loading... |
106 return row.serial; | 106 return row.serial; |
107 default: | 107 default: |
108 NOTREACHED(); | 108 NOTREACHED(); |
109 } | 109 } |
110 return base::string16(); | 110 return base::string16(); |
111 } | 111 } |
112 | 112 |
113 void CertificateSelector::CertificateTableModel::SetObserver( | 113 void CertificateSelector::CertificateTableModel::SetObserver( |
114 ui::TableModelObserver* observer) {} | 114 ui::TableModelObserver* observer) {} |
115 | 115 |
116 CertificateSelector::CertificateSelector( | 116 CertificateSelector::CertificateSelector(net::ClientCertIdentityList identities, |
117 const net::CertificateList& certificates, | 117 content::WebContents* web_contents) |
118 content::WebContents* web_contents) | |
119 : web_contents_(web_contents), table_(nullptr), view_cert_button_(nullptr) { | 118 : web_contents_(web_contents), table_(nullptr), view_cert_button_(nullptr) { |
120 CHECK(web_contents_); | 119 CHECK(web_contents_); |
121 | 120 |
122 // |provider_names| and |certificates_| are parallel arrays. | 121 // |provider_names| and |identities_| are parallel arrays. |
123 // The entry at index |i| is the provider name for |certificates_[i]|. | 122 // The entry at index |i| is the provider name for |identities_[i]|. |
124 std::vector<std::string> provider_names; | 123 std::vector<std::string> provider_names; |
125 #if defined(OS_CHROMEOS) | 124 #if defined(OS_CHROMEOS) |
126 chromeos::CertificateProviderService* service = | 125 chromeos::CertificateProviderService* service = |
127 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( | 126 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( |
128 web_contents->GetBrowserContext()); | 127 web_contents->GetBrowserContext()); |
129 extensions::ExtensionRegistry* extension_registry = | 128 extensions::ExtensionRegistry* extension_registry = |
130 extensions::ExtensionRegistryFactory::GetForBrowserContext( | 129 extensions::ExtensionRegistryFactory::GetForBrowserContext( |
131 web_contents->GetBrowserContext()); | 130 web_contents->GetBrowserContext()); |
132 | 131 |
133 for (const auto& cert : certificates) { | 132 for (auto& identity : identities) { |
134 std::string provider_name; | 133 std::string provider_name; |
135 bool has_extension = false; | 134 bool has_extension = false; |
136 std::string extension_id; | 135 std::string extension_id; |
137 if (service->LookUpCertificate(*cert, &has_extension, &extension_id)) { | 136 if (service->LookUpCertificate(*identity->certificate(), &has_extension, |
| 137 &extension_id)) { |
138 if (!has_extension) { | 138 if (!has_extension) { |
139 // This certificate was provided by an extension but isn't provided by | 139 // This certificate was provided by an extension but isn't provided by |
140 // any extension currently. Don't expose it to the user. | 140 // any extension currently. Don't expose it to the user. |
141 continue; | 141 continue; |
142 } | 142 } |
143 const auto* extension = extension_registry->GetExtensionById( | 143 const auto* extension = extension_registry->GetExtensionById( |
144 extension_id, extensions::ExtensionRegistry::ENABLED); | 144 extension_id, extensions::ExtensionRegistry::ENABLED); |
145 if (!extension) { | 145 if (!extension) { |
146 // This extension was unloaded in the meantime. Don't show the | 146 // This extension was unloaded in the meantime. Don't show the |
147 // certificate. | 147 // certificate. |
148 continue; | 148 continue; |
149 } | 149 } |
150 provider_name = extension->short_name(); | 150 provider_name = extension->short_name(); |
151 show_provider_column_ = true; | 151 show_provider_column_ = true; |
152 } // Otherwise the certificate is provided by the platform. | 152 } // Otherwise the certificate is provided by the platform. |
153 | 153 |
154 certificates_.push_back(cert); | 154 identities_.push_back(std::move(identity)); |
155 provider_names.push_back(provider_name); | 155 provider_names.push_back(provider_name); |
156 } | 156 } |
157 #else | 157 #else |
158 provider_names.assign(certificates.size(), std::string()); | 158 provider_names.assign(identities.size(), std::string()); |
159 certificates_ = certificates; | 159 identities_ = std::move(identities); |
160 #endif | 160 #endif |
161 | 161 |
162 model_.reset(new CertificateTableModel(certificates_, provider_names)); | 162 model_.reset(new CertificateTableModel(identities_, provider_names)); |
163 } | 163 } |
164 | 164 |
165 CertificateSelector::~CertificateSelector() { | 165 CertificateSelector::~CertificateSelector() { |
166 table_->SetModel(nullptr); | 166 table_->SetModel(nullptr); |
167 } | 167 } |
168 | 168 |
169 // static | 169 // static |
170 bool CertificateSelector::CanShow(content::WebContents* web_contents) { | 170 bool CertificateSelector::CanShow(content::WebContents* web_contents) { |
171 // GetTopLevelWebContents returns |web_contents| if it is not a guest. | 171 // GetTopLevelWebContents returns |web_contents| if it is not a guest. |
172 content::WebContents* top_level_web_contents = | 172 content::WebContents* top_level_web_contents = |
173 guest_view::GuestViewBase::GetTopLevelWebContents(web_contents); | 173 guest_view::GuestViewBase::GetTopLevelWebContents(web_contents); |
174 return web_modal::WebContentsModalDialogManager::FromWebContents( | 174 return web_modal::WebContentsModalDialogManager::FromWebContents( |
175 top_level_web_contents) != nullptr; | 175 top_level_web_contents) != nullptr; |
176 } | 176 } |
177 | 177 |
178 void CertificateSelector::Show() { | 178 void CertificateSelector::Show() { |
179 constrained_window::ShowWebModalDialogViews(this, web_contents_); | 179 constrained_window::ShowWebModalDialogViews(this, web_contents_); |
180 | 180 |
181 // TODO(isandrk): A certificate that was previously provided by *both* the | 181 // TODO(isandrk): A certificate that was previously provided by *both* the |
182 // platform and an extension will get incorrectly filtered out if the | 182 // platform and an extension will get incorrectly filtered out if the |
183 // extension stops providing it (both instances will be filtered out), hence | 183 // extension stops providing it (both instances will be filtered out), hence |
184 // the |certificates_| array will be empty. Displaying a dialog with an empty | 184 // the |identities_| array will be empty. Displaying a dialog with an empty |
185 // list won't make much sense for the user, and also there are some CHECKs in | 185 // list won't make much sense for the user, and also there are some CHECKs in |
186 // the code that will fail when the list is empty and that's why an early exit | 186 // the code that will fail when the list is empty and that's why an early exit |
187 // is performed here. See crbug.com/641440 for more details. | 187 // is performed here. See crbug.com/641440 for more details. |
188 if (certificates_.empty()) { | 188 if (identities_.empty()) { |
189 GetWidget()->Close(); | 189 GetWidget()->Close(); |
190 return; | 190 return; |
191 } | 191 } |
192 | 192 |
193 // Select the first row automatically. This must be done after the dialog has | 193 // Select the first row automatically. This must be done after the dialog has |
194 // been created. | 194 // been created. |
195 table_->Select(0); | 195 table_->Select(0); |
196 } | 196 } |
197 | 197 |
198 void CertificateSelector::InitWithText( | 198 void CertificateSelector::InitWithText( |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 views::GridLayout::FILL, views::GridLayout::FILL, | 232 views::GridLayout::FILL, views::GridLayout::FILL, |
233 kTableViewWidth, kTableViewHeight); | 233 kTableViewWidth, kTableViewHeight); |
234 | 234 |
235 layout->AddPaddingRow(0, vertical_spacing); | 235 layout->AddPaddingRow(0, vertical_spacing); |
236 } | 236 } |
237 | 237 |
238 ui::TableModel* CertificateSelector::table_model_for_testing() const { | 238 ui::TableModel* CertificateSelector::table_model_for_testing() const { |
239 return model_.get(); | 239 return model_.get(); |
240 } | 240 } |
241 | 241 |
242 net::X509Certificate* CertificateSelector::GetSelectedCert() const { | 242 net::ClientCertIdentity* CertificateSelector::GetSelectedCert() const { |
243 const int selected = table_->FirstSelectedRow(); | 243 const int selected = table_->FirstSelectedRow(); |
244 if (selected < 0) // Nothing is selected in |table_|. | 244 if (selected < 0) // Nothing is selected in |table_|. |
245 return nullptr; | 245 return nullptr; |
246 CHECK_LT(static_cast<size_t>(selected), certificates_.size()); | 246 CHECK_LT(static_cast<size_t>(selected), identities_.size()); |
247 return certificates_[selected].get(); | 247 return identities_[selected].get(); |
| 248 } |
| 249 |
| 250 std::unique_ptr<net::ClientCertIdentity> |
| 251 CertificateSelector::TakeSelectedCert() { |
| 252 const int selected = table_->FirstSelectedRow(); |
| 253 if (selected < 0) // Nothing is selected in |table_|. |
| 254 return nullptr; |
| 255 CHECK_LT(static_cast<size_t>(selected), identities_.size()); |
| 256 return std::move(identities_[selected]); |
248 } | 257 } |
249 | 258 |
250 bool CertificateSelector::CanResize() const { | 259 bool CertificateSelector::CanResize() const { |
251 return true; | 260 return true; |
252 } | 261 } |
253 | 262 |
254 base::string16 CertificateSelector::GetWindowTitle() const { | 263 base::string16 CertificateSelector::GetWindowTitle() const { |
255 return l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE); | 264 return l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE); |
256 } | 265 } |
257 | 266 |
(...skipping 12 matching lines...) Expand all Loading... |
270 this, l10n_util::GetStringUTF16(IDS_PAGE_INFO_CERT_INFO_BUTTON)); | 279 this, l10n_util::GetStringUTF16(IDS_PAGE_INFO_CERT_INFO_BUTTON)); |
271 return view_cert_button_; | 280 return view_cert_button_; |
272 } | 281 } |
273 | 282 |
274 ui::ModalType CertificateSelector::GetModalType() const { | 283 ui::ModalType CertificateSelector::GetModalType() const { |
275 return ui::MODAL_TYPE_CHILD; | 284 return ui::MODAL_TYPE_CHILD; |
276 } | 285 } |
277 | 286 |
278 void CertificateSelector::ButtonPressed(views::Button* sender, | 287 void CertificateSelector::ButtonPressed(views::Button* sender, |
279 const ui::Event& event) { | 288 const ui::Event& event) { |
280 if (sender == view_cert_button_) { | 289 if (sender == view_cert_button_ && GetSelectedCert()) { |
281 net::X509Certificate* const cert = GetSelectedCert(); | 290 ShowCertificateViewer(web_contents_, |
282 if (cert) | 291 web_contents_->GetTopLevelNativeWindow(), |
283 ShowCertificateViewer(web_contents_, | 292 GetSelectedCert()->certificate()); |
284 web_contents_->GetTopLevelNativeWindow(), cert); | |
285 } | 293 } |
286 } | 294 } |
287 | 295 |
288 void CertificateSelector::OnSelectionChanged() { | 296 void CertificateSelector::OnSelectionChanged() { |
289 GetDialogClientView()->ok_button()->SetEnabled(GetSelectedCert() != nullptr); | 297 GetDialogClientView()->ok_button()->SetEnabled(GetSelectedCert() != nullptr); |
290 } | 298 } |
291 | 299 |
292 void CertificateSelector::OnDoubleClick() { | 300 void CertificateSelector::OnDoubleClick() { |
293 if (GetSelectedCert()) | 301 if (GetSelectedCert()) |
294 GetDialogClientView()->AcceptWindow(); | 302 GetDialogClientView()->AcceptWindow(); |
295 } | 303 } |
296 | 304 |
297 } // namespace chrome | 305 } // namespace chrome |
OLD | NEW |