ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / ui / webui / certificate_viewer_webui.cc
blob57efa4d49b8e526ea63163d4354e304d155cd043
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/webui/certificate_viewer_webui.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/i18n/time_formatting.h"
10 #include "base/json/json_writer.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/certificate_viewer.h"
14 #include "chrome/browser/platform_util.h"
15 #include "chrome/browser/ui/browser_dialogs.h"
16 #include "chrome/browser/ui/certificate_dialogs.h"
17 #include "chrome/browser/ui/webui/certificate_viewer_ui.h"
18 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
19 #include "chrome/common/net/x509_certificate_model.h"
20 #include "chrome/common/url_constants.h"
21 #include "chrome/grit/generated_resources.h"
22 #include "content/public/browser/web_contents.h"
23 #include "ui/base/l10n/l10n_util.h"
24 #include "ui/gfx/geometry/size.h"
26 using content::WebContents;
27 using content::WebUIMessageHandler;
28 using web_modal::NativeWebContentsModalDialog;
30 // Shows a certificate using the WebUI certificate viewer.
31 void ShowCertificateViewer(WebContents* web_contents,
32 gfx::NativeWindow parent,
33 net::X509Certificate* cert) {
34 CertificateViewerDialog* dialog = new CertificateViewerDialog(cert);
35 dialog->Show(web_contents, parent);
38 ////////////////////////////////////////////////////////////////////////////////
39 // CertificateViewerDialog
41 CertificateViewerModalDialog::CertificateViewerModalDialog(
42 net::X509Certificate* cert)
43 : cert_(cert), webui_(NULL), window_(NULL) {
44 // Construct the dialog title from the certificate.
45 title_ = l10n_util::GetStringFUTF16(
46 IDS_CERT_INFO_DIALOG_TITLE,
47 base::UTF8ToUTF16(
48 x509_certificate_model::GetTitle(cert_->os_cert_handle())));
51 CertificateViewerModalDialog::~CertificateViewerModalDialog() {
54 void CertificateViewerModalDialog::Show(content::WebContents* web_contents,
55 gfx::NativeWindow parent) {
56 window_ = chrome::ShowWebDialog(parent,
57 web_contents->GetBrowserContext(),
58 this);
61 NativeWebContentsModalDialog
62 CertificateViewerModalDialog::GetNativeWebContentsModalDialog() {
63 #if defined(USE_AURA)
64 return window_;
65 #else
66 NOTREACHED();
67 return NULL;
68 #endif
71 ui::ModalType CertificateViewerModalDialog::GetDialogModalType() const {
72 return ui::MODAL_TYPE_SYSTEM;
75 base::string16 CertificateViewerModalDialog::GetDialogTitle() const {
76 return title_;
79 GURL CertificateViewerModalDialog::GetDialogContentURL() const {
80 return GURL(chrome::kChromeUICertificateViewerDialogURL);
83 void CertificateViewerModalDialog::GetWebUIMessageHandlers(
84 std::vector<WebUIMessageHandler*>* handlers) const {
85 handlers->push_back(new CertificateViewerDialogHandler(
86 const_cast<CertificateViewerModalDialog*>(this), cert_.get()));
89 void CertificateViewerModalDialog::GetDialogSize(gfx::Size* size) const {
90 const int kDefaultWidth = 544;
91 const int kDefaultHeight = 628;
92 size->SetSize(kDefaultWidth, kDefaultHeight);
95 std::string CertificateViewerModalDialog::GetDialogArgs() const {
96 std::string data;
98 // Certificate information. The keys in this dictionary's general key
99 // correspond to the IDs in the Html page.
100 base::DictionaryValue cert_info;
101 net::X509Certificate::OSCertHandle cert_hnd = cert_->os_cert_handle();
103 // Get the certificate chain.
104 net::X509Certificate::OSCertHandles cert_chain;
105 cert_chain.push_back(cert_->os_cert_handle());
106 const net::X509Certificate::OSCertHandles& certs =
107 cert_->GetIntermediateCertificates();
108 cert_chain.insert(cert_chain.end(), certs.begin(), certs.end());
110 // Certificate usage.
111 std::vector<std::string> usages;
112 x509_certificate_model::GetUsageStrings(cert_hnd, &usages);
113 std::string usagestr;
114 for (std::vector<std::string>::iterator it = usages.begin();
115 it != usages.end(); ++it) {
116 if (usagestr.length() > 0) {
117 usagestr += "\n";
119 usagestr += *it;
121 cert_info.SetString("general.usages", usagestr);
123 // Standard certificate details.
124 const std::string alternative_text =
125 l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT);
126 cert_info.SetString("general.title", l10n_util::GetStringFUTF8(
127 IDS_CERT_INFO_DIALOG_TITLE,
128 base::UTF8ToUTF16(x509_certificate_model::GetTitle(
129 cert_chain.front()))));
131 // Issued to information.
132 cert_info.SetString("general.issued-cn",
133 x509_certificate_model::GetSubjectCommonName(cert_hnd, alternative_text));
134 cert_info.SetString("general.issued-o",
135 x509_certificate_model::GetSubjectOrgName(cert_hnd, alternative_text));
136 cert_info.SetString("general.issued-ou",
137 x509_certificate_model::GetSubjectOrgUnitName(cert_hnd,
138 alternative_text));
139 cert_info.SetString("general.issued-sn",
140 x509_certificate_model::GetSerialNumberHexified(cert_hnd,
141 alternative_text));
143 // Issuer information.
144 cert_info.SetString("general.issuer-cn",
145 x509_certificate_model::GetIssuerCommonName(cert_hnd, alternative_text));
146 cert_info.SetString("general.issuer-o",
147 x509_certificate_model::GetIssuerOrgName(cert_hnd, alternative_text));
148 cert_info.SetString("general.issuer-ou",
149 x509_certificate_model::GetIssuerOrgUnitName(cert_hnd, alternative_text));
151 // Validity period.
152 base::Time issued, expires;
153 std::string issued_str, expires_str;
154 if (x509_certificate_model::GetTimes(cert_hnd, &issued, &expires)) {
155 issued_str = base::UTF16ToUTF8(
156 base::TimeFormatShortDateNumeric(issued));
157 expires_str = base::UTF16ToUTF8(
158 base::TimeFormatShortDateNumeric(expires));
159 } else {
160 issued_str = alternative_text;
161 expires_str = alternative_text;
163 cert_info.SetString("general.issue-date", issued_str);
164 cert_info.SetString("general.expiry-date", expires_str);
166 cert_info.SetString("general.sha256",
167 x509_certificate_model::HashCertSHA256(cert_hnd));
168 cert_info.SetString("general.sha1",
169 x509_certificate_model::HashCertSHA1(cert_hnd));
171 // Certificate hierarchy is constructed from bottom up.
172 base::ListValue* children = NULL;
173 int index = 0;
174 for (net::X509Certificate::OSCertHandles::const_iterator i =
175 cert_chain.begin(); i != cert_chain.end(); ++i, ++index) {
176 base::DictionaryValue* cert_node = new base::DictionaryValue();
177 base::ListValue cert_details;
178 cert_node->SetString("label", x509_certificate_model::GetTitle(*i).c_str());
179 cert_node->SetDouble("payload.index", index);
180 // Add the child from the previous iteration.
181 if (children)
182 cert_node->Set("children", children);
184 // Add this node to the children list for the next iteration.
185 children = new base::ListValue();
186 children->Append(cert_node);
188 // Set the last node as the top of the certificate hierarchy.
189 cert_info.Set("hierarchy", children);
191 base::JSONWriter::Write(&cert_info, &data);
193 return data;
196 void CertificateViewerModalDialog::OnDialogShown(
197 content::WebUI* webui,
198 content::RenderViewHost* render_view_host) {
199 webui_ = webui;
202 void CertificateViewerModalDialog::OnDialogClosed(
203 const std::string& json_retval) {
206 void CertificateViewerModalDialog::OnCloseContents(WebContents* source,
207 bool* out_close_dialog) {
208 if (out_close_dialog)
209 *out_close_dialog = true;
212 bool CertificateViewerModalDialog::ShouldShowDialogTitle() const {
213 return true;
216 ////////////////////////////////////////////////////////////////////////////////
217 // CertificateViewerDialog
219 CertificateViewerDialog::CertificateViewerDialog(net::X509Certificate* cert)
220 : CertificateViewerModalDialog(cert),
221 dialog_(NULL) {
224 CertificateViewerDialog::~CertificateViewerDialog() {
227 void CertificateViewerDialog::Show(WebContents* web_contents,
228 gfx::NativeWindow parent) {
229 // TODO(bshe): UI tweaks needed for Aura HTML Dialog, such as adding padding
230 // on the title for Aura ConstrainedWebDialogUI.
231 dialog_ = ShowConstrainedWebDialog(web_contents->GetBrowserContext(), this,
232 web_contents);
235 NativeWebContentsModalDialog
236 CertificateViewerDialog::GetNativeWebContentsModalDialog() {
237 return dialog_->GetNativeDialog();
240 GURL CertificateViewerDialog::GetDialogContentURL() const {
241 return GURL(chrome::kChromeUICertificateViewerURL);
244 ui::ModalType CertificateViewerDialog::GetDialogModalType() const {
245 return ui::MODAL_TYPE_NONE;
248 ////////////////////////////////////////////////////////////////////////////////
249 // CertificateViewerDialogHandler
251 CertificateViewerDialogHandler::CertificateViewerDialogHandler(
252 CertificateViewerModalDialog* dialog,
253 net::X509Certificate* cert)
254 : cert_(cert), dialog_(dialog) {
255 cert_chain_.push_back(cert_->os_cert_handle());
256 const net::X509Certificate::OSCertHandles& certs =
257 cert_->GetIntermediateCertificates();
258 cert_chain_.insert(cert_chain_.end(), certs.begin(), certs.end());
261 CertificateViewerDialogHandler::~CertificateViewerDialogHandler() {
264 void CertificateViewerDialogHandler::RegisterMessages() {
265 web_ui()->RegisterMessageCallback("exportCertificate",
266 base::Bind(&CertificateViewerDialogHandler::ExportCertificate,
267 base::Unretained(this)));
268 web_ui()->RegisterMessageCallback("requestCertificateFields",
269 base::Bind(&CertificateViewerDialogHandler::RequestCertificateFields,
270 base::Unretained(this)));
273 void CertificateViewerDialogHandler::ExportCertificate(
274 const base::ListValue* args) {
275 int cert_index = GetCertificateIndex(args);
276 if (cert_index < 0)
277 return;
279 NativeWebContentsModalDialog window =
280 platform_util::GetTopLevel(dialog_->GetNativeWebContentsModalDialog());
281 ShowCertExportDialog(web_ui()->GetWebContents(),
282 window,
283 cert_chain_.begin() + cert_index,
284 cert_chain_.end());
287 void CertificateViewerDialogHandler::RequestCertificateFields(
288 const base::ListValue* args) {
289 int cert_index = GetCertificateIndex(args);
290 if (cert_index < 0)
291 return;
293 net::X509Certificate::OSCertHandle cert = cert_chain_[cert_index];
295 base::ListValue root_list;
296 base::DictionaryValue* node_details;
297 base::DictionaryValue* alt_node_details;
298 base::ListValue* cert_sub_fields;
299 root_list.Append(node_details = new base::DictionaryValue());
300 node_details->SetString("label", x509_certificate_model::GetTitle(cert));
302 base::ListValue* cert_fields;
303 node_details->Set("children", cert_fields = new base::ListValue());
304 cert_fields->Append(node_details = new base::DictionaryValue());
306 node_details->SetString("label",
307 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE));
308 node_details->Set("children", cert_fields = new base::ListValue());
310 // Main certificate fields.
311 cert_fields->Append(node_details = new base::DictionaryValue());
312 node_details->SetString("label",
313 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VERSION));
314 std::string version = x509_certificate_model::GetVersion(cert);
315 if (!version.empty())
316 node_details->SetString("payload.val",
317 l10n_util::GetStringFUTF8(IDS_CERT_DETAILS_VERSION_FORMAT,
318 base::UTF8ToUTF16(version)));
320 cert_fields->Append(node_details = new base::DictionaryValue());
321 node_details->SetString("label",
322 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SERIAL_NUMBER));
323 node_details->SetString("payload.val",
324 x509_certificate_model::GetSerialNumberHexified(cert,
325 l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT)));
327 cert_fields->Append(node_details = new base::DictionaryValue());
328 node_details->SetString("label",
329 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG));
330 node_details->SetString("payload.val",
331 x509_certificate_model::ProcessSecAlgorithmSignature(cert));
333 cert_fields->Append(node_details = new base::DictionaryValue());
334 node_details->SetString("label",
335 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_ISSUER));
336 node_details->SetString("payload.val",
337 x509_certificate_model::GetIssuerName(cert));
339 // Validity period.
340 cert_fields->Append(node_details = new base::DictionaryValue());
341 node_details->SetString("label",
342 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VALIDITY));
344 node_details->Set("children", cert_sub_fields = new base::ListValue());
345 cert_sub_fields->Append(node_details = new base::DictionaryValue());
346 node_details->SetString("label",
347 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_BEFORE));
348 cert_sub_fields->Append(alt_node_details = new base::DictionaryValue());
349 alt_node_details->SetString("label",
350 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_AFTER));
351 base::Time issued, expires;
352 if (x509_certificate_model::GetTimes(cert, &issued, &expires)) {
353 node_details->SetString(
354 "payload.val",
355 base::UTF16ToUTF8(
356 base::TimeFormatShortDateAndTimeWithTimeZone(issued)));
357 alt_node_details->SetString(
358 "payload.val",
359 base::UTF16ToUTF8(
360 base::TimeFormatShortDateAndTimeWithTimeZone(expires)));
363 cert_fields->Append(node_details = new base::DictionaryValue());
364 node_details->SetString("label",
365 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT));
366 node_details->SetString("payload.val",
367 x509_certificate_model::GetSubjectName(cert));
369 // Subject key information.
370 cert_fields->Append(node_details = new base::DictionaryValue());
371 node_details->SetString("label",
372 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_INFO));
374 node_details->Set("children", cert_sub_fields = new base::ListValue());
375 cert_sub_fields->Append(node_details = new base::DictionaryValue());
376 node_details->SetString("label",
377 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_ALG));
378 node_details->SetString("payload.val",
379 x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(cert));
380 cert_sub_fields->Append(node_details = new base::DictionaryValue());
381 node_details->SetString("label",
382 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY));
383 node_details->SetString("payload.val",
384 x509_certificate_model::ProcessSubjectPublicKeyInfo(cert));
386 // Extensions.
387 x509_certificate_model::Extensions extensions;
388 x509_certificate_model::GetExtensions(
389 l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_CRITICAL),
390 l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_NON_CRITICAL),
391 cert, &extensions);
393 if (!extensions.empty()) {
394 cert_fields->Append(node_details = new base::DictionaryValue());
395 node_details->SetString("label",
396 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_EXTENSIONS));
398 node_details->Set("children", cert_sub_fields = new base::ListValue());
399 for (x509_certificate_model::Extensions::const_iterator i =
400 extensions.begin(); i != extensions.end(); ++i) {
401 cert_sub_fields->Append(node_details = new base::DictionaryValue());
402 node_details->SetString("label", i->name);
403 node_details->SetString("payload.val", i->value);
407 cert_fields->Append(node_details = new base::DictionaryValue());
408 node_details->SetString("label",
409 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG));
410 node_details->SetString("payload.val",
411 x509_certificate_model::ProcessSecAlgorithmSignatureWrap(cert));
413 cert_fields->Append(node_details = new base::DictionaryValue());
414 node_details->SetString("label",
415 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_VALUE));
416 node_details->SetString("payload.val",
417 x509_certificate_model::ProcessRawBitsSignatureWrap(cert));
419 cert_fields->Append(node_details = new base::DictionaryValue());
420 node_details->SetString("label",
421 l10n_util::GetStringUTF8(IDS_CERT_INFO_FINGERPRINTS_GROUP));
422 node_details->Set("children", cert_sub_fields = new base::ListValue());
424 cert_sub_fields->Append(node_details = new base::DictionaryValue());
425 node_details->SetString("label",
426 l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL));
427 node_details->SetString("payload.val",
428 x509_certificate_model::HashCertSHA256(cert));
429 cert_sub_fields->Append(node_details = new base::DictionaryValue());
430 node_details->SetString("label",
431 l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA1_FINGERPRINT_LABEL));
432 node_details->SetString("payload.val",
433 x509_certificate_model::HashCertSHA1(cert));
435 // Send certificate information to javascript.
436 web_ui()->CallJavascriptFunction("cert_viewer.getCertificateFields",
437 root_list);
440 int CertificateViewerDialogHandler::GetCertificateIndex(
441 const base::ListValue* args) const {
442 int cert_index;
443 double val;
444 if (!(args->GetDouble(0, &val)))
445 return -1;
446 cert_index = static_cast<int>(val);
447 if (cert_index < 0 || cert_index >= static_cast<int>(cert_chain_.size()))
448 return -1;
449 return cert_index;