summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorflackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-16 16:18:18 +0000
committerflackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-16 16:18:18 +0000
commitb231a08c6a523506b972ed2ce834f8aabde3b577 (patch)
tree1502a73a79adc6a8bb727a843f423a6b9a6af3ec /chrome
parentdd67ef20564c2a7f69e0a5c69ef0e933b052e28a (diff)
downloadchromium_src-b231a08c6a523506b972ed2ce834f8aabde3b577.zip
chromium_src-b231a08c6a523506b972ed2ce834f8aabde3b577.tar.gz
chromium_src-b231a08c6a523506b972ed2ce834f8aabde3b577.tar.bz2
Add export function to WebUI certificate viewer.
This adds the export certificate function to the WebUI certificate viewer. Additionally this moves the implementation of extracting certificate details to chrome/browser/ui/webui/certificate_viewer.cc eliminating the need to pass a hex encoded certificate pointer through the WebUI javascript. BUG=None TEST=Manually tested that you can export a certificate. Review URL: http://codereview.chromium.org/7528027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96955 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/resources/certificate_viewer.html1
-rw-r--r--chrome/browser/resources/certificate_viewer.js54
-rw-r--r--chrome/browser/ui/webui/certificate_viewer.cc324
-rw-r--r--chrome/browser/ui/webui/certificate_viewer.h50
-rw-r--r--chrome/browser/ui/webui/certificate_viewer_ui.cc269
-rw-r--r--chrome/browser/ui/webui/certificate_viewer_ui.h14
6 files changed, 394 insertions, 318 deletions
diff --git a/chrome/browser/resources/certificate_viewer.html b/chrome/browser/resources/certificate_viewer.html
index 04d565a..5737483 100644
--- a/chrome/browser/resources/certificate_viewer.html
+++ b/chrome/browser/resources/certificate_viewer.html
@@ -102,6 +102,7 @@
<div id="cert-field-value-section" class="vertical-box">
<span class="title" i18n-content="certFieldVal"></span>
<div id="cert-field-value" class="section-contents"></div>
+ <button id="export" i18n-content="export"></button>
</div>
</tabpanel>
</tabpanels>
diff --git a/chrome/browser/resources/certificate_viewer.js b/chrome/browser/resources/certificate_viewer.js
index 1f4cdcc..b683ca7 100644
--- a/chrome/browser/resources/certificate_viewer.js
+++ b/chrome/browser/resources/certificate_viewer.js
@@ -13,6 +13,7 @@ cr.define('cert_viewer', function() {
$('close').onclick = function() {
window.close();
}
+ $('export').onclick = exportCertificate;
cr.ui.decorate('tabbox', cr.ui.TabBox);
initializeTree($('hierarchy'), showCertificateFields);
@@ -20,8 +21,7 @@ cr.define('cert_viewer', function() {
i18nTemplate.process(document, templateData);
stripGtkAccessorKeys();
- var args = JSON.parse(chrome.dialogArguments);
- chrome.send('requestCertificateInfo', [args.cert]);
+ chrome.send('requestCertificateInfo');
}
/**
@@ -43,10 +43,11 @@ cr.define('cert_viewer', function() {
* translated strings could be added / modified to remove the & sign.
*/
function stripGtkAccessorKeys() {
- var tabs = $('tabs').childNodes;
- for (var i = 0; i < tabs.length; i++) {
- tabs[i].textContent = tabs[i].textContent.replace('&','');
- }
+ // Copy all the tab labels into an array.
+ var nodes = Array.prototype.slice.call($('tabs').childNodes, 0);
+ nodes.push($('export'));
+ for (var i = 0; i < nodes.length; i++)
+ nodes[i].textContent = nodes[i].textContent.replace('&','');
}
/**
@@ -105,20 +106,37 @@ cr.define('cert_viewer', function() {
}
/**
- * Show certificate fields for the selected certificate in the hierarchy.
+ * Clear any previous certificate fields in the tree.
*/
- function showCertificateFields() {
+ function clearCertificateFields() {
var treeItem = $('cert-fields');
for (var key in treeItem.detail.children) {
treeItem.remove(treeItem.detail.children[key]);
delete treeItem.detail.children[key];
}
+ }
+
+ /**
+ * Request certificate fields for the selected certificate in the hierarchy.
+ */
+ function showCertificateFields() {
+ clearCertificateFields();
var item = $('hierarchy').selectedItem;
- if (item && item.detail.payload.fields) {
- treeItem.add(treeItem.detail.children['root'] =
- constructTree(item.detail.payload.fields[0]));
- revealTree(treeItem);
- }
+ if (item && item.detail.payload.index !== undefined)
+ chrome.send('requestCertificateFields', [item.detail.payload.index]);
+ }
+
+ /**
+ * Show the returned certificate fields for the selected certificate.
+ * @param {Object} certFields A dictionary containing the fields tree
+ * structure.
+ */
+ function getCertificateFields(certFields) {
+ clearCertificateFields();
+ var treeItem = $('cert-fields');
+ treeItem.add(treeItem.detail.children['root'] =
+ constructTree(certFields[0]));
+ revealTree(treeItem);
}
/**
@@ -132,9 +150,19 @@ cr.define('cert_viewer', function() {
$('cert-field-value').textContent = '';
}
+ /**
+ * Export the selected certificate.
+ */
+ function exportCertificate() {
+ var item = $('hierarchy').selectedItem;
+ if (item && item.detail.payload.index !== undefined)
+ chrome.send('exportCertificate', [item.detail.payload.index]);
+ }
+
return {
initialize: initialize,
getCertificateInfo: getCertificateInfo,
+ getCertificateFields: getCertificateFields,
};
});
diff --git a/chrome/browser/ui/webui/certificate_viewer.cc b/chrome/browser/ui/webui/certificate_viewer.cc
index 03f2db1..e7a0f7c 100644
--- a/chrome/browser/ui/webui/certificate_viewer.cc
+++ b/chrome/browser/ui/webui/certificate_viewer.cc
@@ -2,16 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/json/json_writer.h"
+#include "base/i18n/time_formatting.h"
#include "base/utf_string_conversions.h"
#include "base/string_number_conversions.h"
#include "chrome/browser/ui/webui/certificate_viewer.h"
#include "chrome/common/url_constants.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/views/html_dialog_view.h"
+#include "chrome/browser/ui/gtk/certificate_dialogs.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/common/net/x509_certificate_model.h"
+#include "content/browser/tab_contents/tab_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "grit/generated_resources.h"
@@ -29,27 +30,20 @@ void ShowCertificateViewer(gfx::NativeWindow parent,
CertificateViewerDialog::ShowDialog(parent, cert);
}
-void CertificateViewerDialog::ShowDialog(gfx::NativeWindow owning_window,
+////////////////////////////////////////////////////////////////////////////////
+// CertificateViewerDialog
+
+void CertificateViewerDialog::ShowDialog(gfx::NativeWindow parent,
net::X509Certificate* cert) {
Browser* browser = BrowserList::GetLastActive();
DCHECK(browser);
- browser->BrowserShowHtmlDialog(new CertificateViewerDialog(cert),
- owning_window);
-}
-
-// TODO(flackr): This is duplicated from cookies_view_handler.cc
-// Encodes a pointer value into a hex string.
-std::string PointerToHexString(const void* pointer) {
- return base::HexEncode(&pointer, sizeof(pointer));
+ browser->BrowserShowHtmlDialog(new CertificateViewerDialog(parent, cert),
+ parent);
}
-CertificateViewerDialog::CertificateViewerDialog(net::X509Certificate* cert)
- : cert_(cert) {
- // Construct the JSON string with a pointer to the stored certificate.
- DictionaryValue args;
- args.SetString("cert", PointerToHexString(cert_));
- base::JSONWriter::Write(&args, false, &json_args_);
-
+CertificateViewerDialog::CertificateViewerDialog(gfx::NativeWindow parent,
+ net::X509Certificate* cert)
+ : cert_(cert), parent_(parent) {
// Construct the dialog title from the certificate.
net::X509Certificate::OSCertHandles cert_chain;
x509_certificate_model::GetCertChainFromCert(cert_->os_cert_handle(),
@@ -59,7 +53,7 @@ CertificateViewerDialog::CertificateViewerDialog(net::X509Certificate* cert)
}
bool CertificateViewerDialog::IsDialogModal() const {
- return false;
+ return true;
}
string16 CertificateViewerDialog::GetDialogTitle() const {
@@ -72,6 +66,7 @@ GURL CertificateViewerDialog::GetDialogContentURL() const {
void CertificateViewerDialog::GetWebUIMessageHandlers(
std::vector<WebUIMessageHandler*>* handlers) const {
+ handlers->push_back(new CertificateViewerDialogHandler(parent_, cert_));
}
void CertificateViewerDialog::GetDialogSize(gfx::Size* size) const {
@@ -79,7 +74,7 @@ void CertificateViewerDialog::GetDialogSize(gfx::Size* size) const {
}
std::string CertificateViewerDialog::GetDialogArgs() const {
- return json_args_;
+ return std::string();
}
void CertificateViewerDialog::OnDialogClosed(const std::string& json_retval) {
@@ -100,3 +95,292 @@ bool CertificateViewerDialog::HandleContextMenu(
const ContextMenuParams& params) {
return true;
}
+
+////////////////////////////////////////////////////////////////////////////////
+// CertificateViewerDialogHandler
+
+CertificateViewerDialogHandler::CertificateViewerDialogHandler(
+ gfx::NativeWindow parent,
+ net::X509Certificate* cert) : cert_(cert), parent_(parent) {
+ x509_certificate_model::GetCertChainFromCert(cert_->os_cert_handle(),
+ &cert_chain_);
+}
+
+void CertificateViewerDialogHandler::RegisterMessages() {
+ web_ui_->RegisterMessageCallback("exportCertificate",
+ NewCallback(this,
+ &CertificateViewerDialogHandler::ExportCertificate));
+ web_ui_->RegisterMessageCallback("requestCertificateInfo",
+ NewCallback(this,
+ &CertificateViewerDialogHandler::RequestCertificateInfo));
+ web_ui_->RegisterMessageCallback("requestCertificateFields",
+ NewCallback(this,
+ &CertificateViewerDialogHandler::RequestCertificateFields));
+}
+
+void CertificateViewerDialogHandler::ExportCertificate(
+ const base::ListValue* args) {
+ int cert_index;
+ double val;
+ if (!(args->GetDouble(0, &val)))
+ return;
+ cert_index = (int)val;
+ if (cert_index < 0 || cert_index >= (int)cert_chain_.size())
+ return;
+
+ // TODO(flackr): We should be able to use the current dialog's container
+ // window as a parent for the export dialog however chromeos builds fail
+ // to locate the browser for this window. HtmlDialog should probably
+ // behave similar to a window.open popup with an associated Browser
+ // object.
+ ShowCertExportDialog(web_ui_->tab_contents(),
+ parent_,
+ cert_chain_[cert_index]);
+}
+
+void CertificateViewerDialogHandler::RequestCertificateInfo(
+ const base::ListValue* args) {
+ // Certificate information. The keys in this dictionary's general key
+ // correspond to the IDs in the Html page.
+ DictionaryValue cert_info;
+ net::X509Certificate::OSCertHandle cert_hnd = cert_->os_cert_handle();
+
+ // Get the certificate chain.
+ net::X509Certificate::OSCertHandles cert_chain;
+ x509_certificate_model::GetCertChainFromCert(cert_hnd, &cert_chain);
+
+ // Certificate usage.
+ std::vector<std::string> usages;
+ x509_certificate_model::GetUsageStrings(cert_hnd, &usages);
+ std::string usagestr;
+ for (std::vector<std::string>::iterator it = usages.begin();
+ it != usages.end(); ++it) {
+ if (usagestr.length() > 0) {
+ usagestr += "\n";
+ }
+ usagestr += *it;
+ }
+ cert_info.SetString("general.usages", usagestr);
+
+ // Standard certificate details.
+ const std::string alternative_text =
+ l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT);
+ cert_info.SetString("general.title", l10n_util::GetStringFUTF8(
+ IDS_CERT_INFO_DIALOG_TITLE, UTF8ToUTF16(x509_certificate_model::GetTitle(
+ cert_chain.front()))));
+
+ // Issued to information.
+ cert_info.SetString("general.issued-cn",
+ x509_certificate_model::GetSubjectCommonName(cert_hnd, alternative_text));
+ cert_info.SetString("general.issued-o",
+ x509_certificate_model::GetSubjectOrgName(cert_hnd, alternative_text));
+ cert_info.SetString("general.issued-ou",
+ x509_certificate_model::GetSubjectOrgUnitName(cert_hnd,
+ alternative_text));
+ cert_info.SetString("general.issued-sn",
+ x509_certificate_model::GetSerialNumberHexified(cert_hnd,
+ alternative_text));
+
+ // Issuer information.
+ cert_info.SetString("general.issuer-cn",
+ x509_certificate_model::GetIssuerCommonName(cert_hnd, alternative_text));
+ cert_info.SetString("general.issuer-o",
+ x509_certificate_model::GetIssuerOrgName(cert_hnd, alternative_text));
+ cert_info.SetString("general.issuer-ou",
+ x509_certificate_model::GetIssuerOrgUnitName(cert_hnd, alternative_text));
+
+ // Validity period.
+ base::Time issued, expires;
+ std::string issued_str, expires_str;
+ if (x509_certificate_model::GetTimes(cert_hnd, &issued, &expires)) {
+ issued_str = UTF16ToUTF8(
+ base::TimeFormatShortDateNumeric(issued));
+ expires_str = UTF16ToUTF8(
+ base::TimeFormatShortDateNumeric(expires));
+ } else {
+ issued_str = alternative_text;
+ expires_str = alternative_text;
+ }
+ cert_info.SetString("general.issue-date", issued_str);
+ cert_info.SetString("general.expiry-date", expires_str);
+
+ cert_info.SetString("general.sha256",
+ x509_certificate_model::HashCertSHA256(cert_hnd));
+ cert_info.SetString("general.sha1",
+ x509_certificate_model::HashCertSHA1(cert_hnd));
+
+ // Certificate hierarchy is constructed from bottom up.
+ ListValue* children = NULL;
+ int index = 0;
+ for (net::X509Certificate::OSCertHandles::const_iterator i =
+ cert_chain.begin(); i != cert_chain.end(); ++i, ++index) {
+ DictionaryValue* cert_node = new DictionaryValue();
+ ListValue cert_details;
+ cert_node->SetString("label", x509_certificate_model::GetTitle(*i).c_str());
+ cert_node->SetDouble("payload.index", index);
+ // Add the child from the previous iteration.
+ if (children)
+ cert_node->Set("children", children);
+
+ // Add this node to the children list for the next iteration.
+ children = new ListValue();
+ children->Append(cert_node);
+ }
+ // Set the last node as the top of the certificate hierarchy.
+ cert_info.Set("hierarchy", children);
+
+ // Send certificate information to javascript.
+ web_ui_->CallJavascriptFunction("cert_viewer.getCertificateInfo", cert_info);
+}
+
+void CertificateViewerDialogHandler::RequestCertificateFields(
+ const base::ListValue* args) {
+ int cert_index;
+ double val;
+ if (!(args->GetDouble(0, &val)))
+ return;
+ cert_index = (int)val;
+ if (cert_index < 0 || cert_index >= (int)cert_chain_.size())
+ return;
+ net::X509Certificate::OSCertHandle cert = cert_chain_[cert_index];
+
+ ListValue root_list;
+ DictionaryValue* node_details;
+ DictionaryValue* alt_node_details;
+ ListValue* cert_sub_fields;
+ root_list.Append(node_details = new DictionaryValue());
+ node_details->SetString("label", x509_certificate_model::GetTitle(cert));
+
+ ListValue* cert_fields;
+ node_details->Set("children", cert_fields = new ListValue());
+ cert_fields->Append(node_details = new DictionaryValue());
+
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE));
+ node_details->Set("children", cert_fields = new ListValue());
+
+ // Main certificate fields.
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VERSION));
+ std::string version = x509_certificate_model::GetVersion(cert);
+ if (!version.empty())
+ node_details->SetString("payload.val",
+ l10n_util::GetStringFUTF8(IDS_CERT_DETAILS_VERSION_FORMAT,
+ UTF8ToUTF16(version)));
+
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SERIAL_NUMBER));
+ node_details->SetString("payload.val",
+ x509_certificate_model::GetSerialNumberHexified(cert,
+ l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT)));
+
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG));
+ node_details->SetString("payload.val",
+ x509_certificate_model::ProcessSecAlgorithmSignature(cert));
+
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_ISSUER));
+ node_details->SetString("payload.val",
+ x509_certificate_model::GetIssuerName(cert));
+
+ // Validity period.
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VALIDITY));
+
+ node_details->Set("children", cert_sub_fields = new ListValue());
+ cert_sub_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_BEFORE));
+ cert_sub_fields->Append(alt_node_details = new DictionaryValue());
+ alt_node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_AFTER));
+ base::Time issued, expires;
+ if (x509_certificate_model::GetTimes(cert, &issued, &expires)) {
+ node_details->SetString("payload.val",
+ UTF16ToUTF8(base::TimeFormatShortDateAndTime(issued)));
+ alt_node_details->SetString("payload.val",
+ UTF16ToUTF8(base::TimeFormatShortDateAndTime(expires)));
+ }
+
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT));
+ node_details->SetString("payload.val",
+ x509_certificate_model::GetSubjectName(cert));
+
+ // Subject key information.
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_INFO));
+
+ node_details->Set("children", cert_sub_fields = new ListValue());
+ cert_sub_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_ALG));
+ node_details->SetString("payload.val",
+ x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(cert));
+ cert_sub_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY));
+ node_details->SetString("payload.val",
+ x509_certificate_model::ProcessSubjectPublicKeyInfo(cert));
+
+ // Extensions.
+ x509_certificate_model::Extensions extensions;
+ x509_certificate_model::GetExtensions(
+ l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_CRITICAL),
+ l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_NON_CRITICAL),
+ cert, &extensions);
+
+ if (!extensions.empty()) {
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_EXTENSIONS));
+
+ node_details->Set("children", cert_sub_fields = new ListValue());
+ for (x509_certificate_model::Extensions::const_iterator i =
+ extensions.begin(); i != extensions.end(); ++i) {
+ cert_sub_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label", i->name);
+ node_details->SetString("payload.val", i->value);
+ }
+ }
+
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG));
+ node_details->SetString("payload.val",
+ x509_certificate_model::ProcessSecAlgorithmSignatureWrap(cert));
+
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_VALUE));
+ node_details->SetString("payload.val",
+ x509_certificate_model::ProcessRawBitsSignatureWrap(cert));
+
+ cert_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_INFO_FINGERPRINTS_GROUP));
+ node_details->Set("children", cert_sub_fields = new ListValue());
+
+ cert_sub_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL));
+ node_details->SetString("payload.val",
+ x509_certificate_model::HashCertSHA256(cert));
+ cert_sub_fields->Append(node_details = new DictionaryValue());
+ node_details->SetString("label",
+ l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA1_FINGERPRINT_LABEL));
+ node_details->SetString("payload.val",
+ x509_certificate_model::HashCertSHA1(cert));
+
+ // Send certificate information to javascript.
+ web_ui_->CallJavascriptFunction("cert_viewer.getCertificateFields",
+ root_list);
+}
diff --git a/chrome/browser/ui/webui/certificate_viewer.h b/chrome/browser/ui/webui/certificate_viewer.h
index bc52b416..1ebda6a 100644
--- a/chrome/browser/ui/webui/certificate_viewer.h
+++ b/chrome/browser/ui/webui/certificate_viewer.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_WEBUI_CERTIFICATE_VIEWER_H_
#pragma once
+#include "base/values.h"
#include "chrome/browser/ui/webui/html_dialog_ui.h"
#include "net/base/x509_certificate.h"
#include "ui/gfx/native_widget_types.h"
@@ -21,14 +22,15 @@ void ShowCertificateViewer(gfx::NativeWindow parent,
class CertificateViewerDialog : private HtmlDialogUIDelegate {
public:
// Shows the certificate viewer dialog for the passed in certificate.
- static void ShowDialog(gfx::NativeWindow owning_window,
+ static void ShowDialog(gfx::NativeWindow parent,
net::X509Certificate* cert);
private:
// Construct a certificate viewer for the passed in certificate. A reference
// to the certificate pointer is added for the lifetime of the certificate
// viewer.
- explicit CertificateViewerDialog(net::X509Certificate* cert);
+ explicit CertificateViewerDialog(gfx::NativeWindow parent,
+ net::X509Certificate* cert);
// Overridden from HtmlDialogUI::Delegate:
virtual bool IsDialogModal() const OVERRIDE;
@@ -47,8 +49,8 @@ class CertificateViewerDialog : private HtmlDialogUIDelegate {
// The certificate being viewed.
scoped_refptr<net::X509Certificate> cert_;
- // The argument string for the dialog which passes the certificate pointer.
- std::string json_args_;
+ // The owning window.
+ gfx::NativeWindow parent_;
// The title of the certificate viewer dialog, Certificate Viewer: CN.
string16 title_;
@@ -56,4 +58,44 @@ class CertificateViewerDialog : private HtmlDialogUIDelegate {
DISALLOW_COPY_AND_ASSIGN(CertificateViewerDialog);
};
+// Dialog handler which handles calls from the JS WebUI code to view certificate
+// details and export the certificate.
+class CertificateViewerDialogHandler : public WebUIMessageHandler {
+ public:
+ CertificateViewerDialogHandler(gfx::NativeWindow parent,
+ net::X509Certificate* cert);
+
+ // Overridden from WebUIMessageHandler
+ virtual void RegisterMessages();
+
+ private:
+ // Brings up the export certificate dialog for the chosen certificate in the
+ // chain.
+ //
+ // The input is an integer index to the certificate in the chain to export.
+ void ExportCertificate(const base::ListValue* args);
+
+ // Gets the details for a specific certificate in the certificate chain. Calls
+ // the javascript function cert_viewer.getCertificateFields with a tree
+ // structure containing the fields and values for certain nodes.
+ //
+ // The input is an integer index to the certificate in the chain to view.
+ void RequestCertificateFields(const base::ListValue* args);
+
+ // Extracts the certificate details and returns them to the javascript
+ // function cert_viewer.getCertificateInfo in a dictionary structure.
+ void RequestCertificateInfo(const base::ListValue* args);
+
+ // The certificate being viewed.
+ scoped_refptr<net::X509Certificate> cert_;
+
+ // The parent window.
+ gfx::NativeWindow parent_;
+
+ // The certificate chain.
+ net::X509Certificate::OSCertHandles cert_chain_;
+
+ DISALLOW_COPY_AND_ASSIGN(CertificateViewerDialogHandler);
+};
+
#endif // CHROME_BROWSER_UI_WEBUI_CERTIFICATE_VIEWER_H_
diff --git a/chrome/browser/ui/webui/certificate_viewer_ui.cc b/chrome/browser/ui/webui/certificate_viewer_ui.cc
index 57cf1da..c67f126 100644
--- a/chrome/browser/ui/webui/certificate_viewer_ui.cc
+++ b/chrome/browser/ui/webui/certificate_viewer_ui.cc
@@ -4,19 +4,12 @@
#include "chrome/browser/ui/webui/certificate_viewer_ui.h"
-#include "base/string_number_conversions.h"
-#include "base/i18n/time_formatting.h"
-#include "base/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/webui/chrome_web_ui_data_source.h"
#include "chrome/common/url_constants.h"
-#include "chrome/common/net/x509_certificate_model.h"
-#include "content/browser/cert_store.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
-#include "net/base/x509_certificate.h"
-#include "ui/base/l10n/l10n_util.h"
CertificateViewerUI::CertificateViewerUI(TabContents* contents)
: HtmlDialogUI(contents) {
@@ -25,14 +18,12 @@ CertificateViewerUI::CertificateViewerUI(TabContents* contents)
ChromeWebUIDataSource* html_source =
new ChromeWebUIDataSource(chrome::kChromeUICertificateViewerHost);
- // Register callback handler to retrieve certificate information.
- RegisterMessageCallback("requestCertificateInfo",
- NewCallback(this, &CertificateViewerUI::RequestCertificateInfo));
-
// Localized strings.
html_source->AddLocalizedString("general", IDS_CERT_INFO_GENERAL_TAB_LABEL);
html_source->AddLocalizedString("details", IDS_CERT_INFO_DETAILS_TAB_LABEL);
html_source->AddLocalizedString("close", IDS_CLOSE);
+ html_source->AddLocalizedString("export",
+ IDS_CERT_DETAILS_EXPORT_CERTIFICATE);
html_source->AddLocalizedString("usages",
IDS_CERT_INFO_VERIFIED_USAGES_GROUP);
html_source->AddLocalizedString("issuedTo", IDS_CERT_INFO_SUBJECT_GROUP);
@@ -71,259 +62,3 @@ CertificateViewerUI::CertificateViewerUI(TabContents* contents)
CertificateViewerUI::~CertificateViewerUI() {
}
-
-// TODO(flackr): This is duplicated from cookies_view_handler.cc
-// Decodes a pointer from a hex string.
-void* HexStringToPointer(const std::string& str) {
- std::vector<uint8> buffer;
- if (!base::HexStringToBytes(str, &buffer) ||
- buffer.size() != sizeof(void*)) {
- return NULL;
- }
-
- return *reinterpret_cast<void**>(&buffer[0]);
-}
-
-// Returns the certificate information of the requested certificate id from
-// the CertStore to the javascript handler.
-void CertificateViewerUI::RequestCertificateInfo(const ListValue* args) {
- // The certificate id should be in the first argument.
- std::string val;
- if (!(args->GetString(0, &val))) {
- return;
- }
- net::X509Certificate* cert = static_cast<net::X509Certificate*>(
- HexStringToPointer(val));
-
- // Certificate information. The keys in this dictionary's general key
- // correspond to the IDs in the Html page.
- DictionaryValue cert_info;
- net::X509Certificate::OSCertHandle cert_hnd = cert->os_cert_handle();
-
- // Get the certificate chain.
- net::X509Certificate::OSCertHandles cert_chain;
- x509_certificate_model::GetCertChainFromCert(cert_hnd, &cert_chain);
-
- // Certificate usage.
- std::vector<std::string> usages;
- x509_certificate_model::GetUsageStrings(cert_hnd, &usages);
- std::string usagestr;
- for (std::vector<std::string>::iterator it = usages.begin();
- it != usages.end(); ++it) {
- if (usagestr.length() > 0) {
- usagestr += "\n";
- }
- usagestr += *it;
- }
- cert_info.SetString("general.usages", usagestr);
-
- // Standard certificate details.
- const std::string alternative_text =
- l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT);
- cert_info.SetString("general.title", l10n_util::GetStringFUTF8(
- IDS_CERT_INFO_DIALOG_TITLE, UTF8ToUTF16(x509_certificate_model::GetTitle(
- cert_chain.front()))));
-
- // Issued to information.
- cert_info.SetString("general.issued-cn",
- x509_certificate_model::GetSubjectCommonName(cert_hnd, alternative_text));
- cert_info.SetString("general.issued-o",
- x509_certificate_model::GetSubjectOrgName(cert_hnd, alternative_text));
- cert_info.SetString("general.issued-ou",
- x509_certificate_model::GetSubjectOrgUnitName(cert_hnd,
- alternative_text));
- cert_info.SetString("general.issued-sn",
- x509_certificate_model::GetSerialNumberHexified(cert_hnd,
- alternative_text));
-
- // Issuer information.
- cert_info.SetString("general.issuer-cn",
- x509_certificate_model::GetIssuerCommonName(cert_hnd, alternative_text));
- cert_info.SetString("general.issuer-o",
- x509_certificate_model::GetIssuerOrgName(cert_hnd, alternative_text));
- cert_info.SetString("general.issuer-ou",
- x509_certificate_model::GetIssuerOrgUnitName(cert_hnd, alternative_text));
-
- // Validity period.
- base::Time issued, expires;
- std::string issued_str, expires_str;
- if (x509_certificate_model::GetTimes(cert_hnd, &issued, &expires)) {
- issued_str = UTF16ToUTF8(
- base::TimeFormatShortDateNumeric(issued));
- expires_str = UTF16ToUTF8(
- base::TimeFormatShortDateNumeric(expires));
- } else {
- issued_str = alternative_text;
- expires_str = alternative_text;
- }
- cert_info.SetString("general.issue-date", issued_str);
- cert_info.SetString("general.expiry-date", expires_str);
-
- cert_info.SetString("general.sha256",
- x509_certificate_model::HashCertSHA256(cert_hnd));
- cert_info.SetString("general.sha1",
- x509_certificate_model::HashCertSHA1(cert_hnd));
-
- // Certificate hierarchy is constructed from bottom up.
- ListValue* children = NULL;
- for (net::X509Certificate::OSCertHandles::const_iterator i =
- cert_chain.begin(); i != cert_chain.end(); ++i) {
- DictionaryValue* cert_node = new DictionaryValue();
- ListValue cert_details;
- cert_node->SetString("label", x509_certificate_model::GetTitle(*i).c_str());
- cert_node->Set("payload.fields", GetCertificateFields(*i));
- // Add the child from the previous iteration.
- if (children)
- cert_node->Set("children", children);
-
- // Add this node to the children list for the next iteration.
- children = new ListValue();
- children->Append(cert_node);
- }
- // Set the last node as the top of the certificate hierarchy.
- cert_info.Set("hierarchy", children);
-
- // Send certificate information to javascript.
- CallJavascriptFunction("cert_viewer.getCertificateInfo", cert_info);
-}
-
-ListValue* CertificateViewerUI::GetCertificateFields(
- net::X509Certificate::OSCertHandle cert) {
- ListValue* root_list = new ListValue();
- DictionaryValue* node_details;
- DictionaryValue* alt_node_details;
- ListValue* cert_sub_fields;
- root_list->Append(node_details = new DictionaryValue());
- node_details->SetString("label", x509_certificate_model::GetTitle(cert));
-
- ListValue* cert_fields;
- node_details->Set("children", cert_fields = new ListValue());
- cert_fields->Append(node_details = new DictionaryValue());
-
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE));
- node_details->Set("children", cert_fields = new ListValue());
-
- // Main certificate fields.
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VERSION));
- std::string version = x509_certificate_model::GetVersion(cert);
- if (!version.empty())
- node_details->SetString("payload.val",
- l10n_util::GetStringFUTF8(IDS_CERT_DETAILS_VERSION_FORMAT,
- UTF8ToUTF16(version)));
-
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SERIAL_NUMBER));
- node_details->SetString("payload.val",
- x509_certificate_model::GetSerialNumberHexified(cert,
- l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT)));
-
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG));
- node_details->SetString("payload.val",
- x509_certificate_model::ProcessSecAlgorithmSignature(cert));
-
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_ISSUER));
- node_details->SetString("payload.val",
- x509_certificate_model::GetIssuerName(cert));
-
- // Validity period.
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VALIDITY));
-
- node_details->Set("children", cert_sub_fields = new ListValue());
- cert_sub_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_BEFORE));
- cert_sub_fields->Append(alt_node_details = new DictionaryValue());
- alt_node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_AFTER));
- base::Time issued, expires;
- if (x509_certificate_model::GetTimes(cert, &issued, &expires)) {
- node_details->SetString("payload.val",
- UTF16ToUTF8(base::TimeFormatShortDateAndTime(issued)));
- alt_node_details->SetString("payload.val",
- UTF16ToUTF8(base::TimeFormatShortDateAndTime(expires)));
- }
-
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT));
- node_details->SetString("payload.val",
- x509_certificate_model::GetSubjectName(cert));
-
- // Subject key information.
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_INFO));
-
- node_details->Set("children", cert_sub_fields = new ListValue());
- cert_sub_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_ALG));
- node_details->SetString("payload.val",
- x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(cert));
- cert_sub_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY));
- node_details->SetString("payload.val",
- x509_certificate_model::ProcessSubjectPublicKeyInfo(cert));
-
- // Extensions.
- x509_certificate_model::Extensions extensions;
- x509_certificate_model::GetExtensions(
- l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_CRITICAL),
- l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_NON_CRITICAL),
- cert, &extensions);
-
- if (!extensions.empty()) {
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_EXTENSIONS));
-
- node_details->Set("children", cert_sub_fields = new ListValue());
- for (x509_certificate_model::Extensions::const_iterator i =
- extensions.begin(); i != extensions.end(); ++i) {
- cert_sub_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label", i->name);
- node_details->SetString("payload.val", i->value);
- }
- }
-
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG));
- node_details->SetString("payload.val",
- x509_certificate_model::ProcessSecAlgorithmSignatureWrap(cert));
-
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_VALUE));
- node_details->SetString("payload.val",
- x509_certificate_model::ProcessRawBitsSignatureWrap(cert));
-
- cert_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_INFO_FINGERPRINTS_GROUP));
- node_details->Set("children", cert_sub_fields = new ListValue());
-
- cert_sub_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL));
- node_details->SetString("payload.val",
- x509_certificate_model::HashCertSHA256(cert));
- cert_sub_fields->Append(node_details = new DictionaryValue());
- node_details->SetString("label",
- l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA1_FINGERPRINT_LABEL));
- node_details->SetString("payload.val",
- x509_certificate_model::HashCertSHA1(cert));
- return root_list;
-}
-
diff --git a/chrome/browser/ui/webui/certificate_viewer_ui.h b/chrome/browser/ui/webui/certificate_viewer_ui.h
index 926b620..1133d13 100644
--- a/chrome/browser/ui/webui/certificate_viewer_ui.h
+++ b/chrome/browser/ui/webui/certificate_viewer_ui.h
@@ -6,9 +6,7 @@
#define CHROME_BROWSER_UI_WEBUI_CERTIFICATE_VIEWER_UI_H_
#pragma once
-#include "base/values.h"
#include "chrome/browser/ui/webui/html_dialog_ui.h"
-#include "net/base/x509_certificate.h"
// The WebUI for chrome://view-cert
class CertificateViewerUI : public HtmlDialogUI {
@@ -16,18 +14,6 @@ class CertificateViewerUI : public HtmlDialogUI {
explicit CertificateViewerUI(TabContents* contents);
virtual ~CertificateViewerUI();
- protected:
- // Extracts the certificate details and returns them to the javascript
- // function getCertificateInfo in a dictionary structure.
- //
- // The input is an X509Certificate pointer in hex encoded format in the first
- // argument of the args list.
- void RequestCertificateInfo(const ListValue* args);
-
- // Get the details for a specific certificate in the certificate chain. The
- // fields are returned as a tree structure with values for certain nodes.
- ListValue* GetCertificateFields(net::X509Certificate::OSCertHandle cert);
-
DISALLOW_COPY_AND_ASSIGN(CertificateViewerUI);
};