diff options
author | flackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-16 16:18:18 +0000 |
---|---|---|
committer | flackr@chromium.org <flackr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-16 16:18:18 +0000 |
commit | b231a08c6a523506b972ed2ce834f8aabde3b577 (patch) | |
tree | 1502a73a79adc6a8bb727a843f423a6b9a6af3ec /chrome | |
parent | dd67ef20564c2a7f69e0a5c69ef0e933b052e28a (diff) | |
download | chromium_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.html | 1 | ||||
-rw-r--r-- | chrome/browser/resources/certificate_viewer.js | 54 | ||||
-rw-r--r-- | chrome/browser/ui/webui/certificate_viewer.cc | 324 | ||||
-rw-r--r-- | chrome/browser/ui/webui/certificate_viewer.h | 50 | ||||
-rw-r--r-- | chrome/browser/ui/webui/certificate_viewer_ui.cc | 269 | ||||
-rw-r--r-- | chrome/browser/ui/webui/certificate_viewer_ui.h | 14 |
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); }; |