| Index: chrome/browser/ui/webui/certificate_viewer_webui.cc
|
| diff --git a/chrome/browser/ui/webui/certificate_viewer_webui.cc b/chrome/browser/ui/webui/certificate_viewer_webui.cc
|
| index eebe9f1998f233476586b1521c4c6ed7cf46a842..eae1c60fa03cf24b6f4a029bdfb34c46f7192958 100644
|
| --- a/chrome/browser/ui/webui/certificate_viewer_webui.cc
|
| +++ b/chrome/browser/ui/webui/certificate_viewer_webui.cc
|
| @@ -11,9 +11,12 @@
|
| #include "base/bind_helpers.h"
|
| #include "base/i18n/time_formatting.h"
|
| #include "base/json/json_writer.h"
|
| +#include "base/macros.h"
|
| #include "base/memory/ptr_util.h"
|
| #include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/string_piece.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| +#include "base/values.h"
|
| #include "chrome/browser/certificate_viewer.h"
|
| #include "chrome/browser/platform_util.h"
|
| #include "chrome/browser/ui/browser_dialogs.h"
|
| @@ -30,6 +33,84 @@
|
| using content::WebContents;
|
| using content::WebUIMessageHandler;
|
|
|
| +namespace {
|
| +
|
| +// Helper class for building a Value representation of a certificate. The class
|
| +// gathers data for a single node of the representation tree and builds a
|
| +// DictionaryValue out of that.
|
| +class CertNodeBuilder {
|
| + public:
|
| + // Starts the node with "label" set to |label|.
|
| + explicit CertNodeBuilder(base::StringPiece label);
|
| +
|
| + // Convenience version: Converts |label_id| to the corresponding resource
|
| + // string, then delegates to the other constructor.
|
| + explicit CertNodeBuilder(int label_id);
|
| +
|
| + // Builder methods all return |*this| so that they can be chained in single
|
| + // expressions.
|
| +
|
| + // Sets the "payload.val" field. Call this at most once.
|
| + CertNodeBuilder& Payload(base::StringPiece payload);
|
| +
|
| + // Adds |child| in the list keyed "children". Can be called multiple times.
|
| + CertNodeBuilder& Child(std::unique_ptr<base::DictionaryValue> child);
|
| +
|
| + // Similar to Child, but if the argument is null, then this does not add
|
| + // anything.
|
| + CertNodeBuilder& ChildIfNotNull(std::unique_ptr<base::DictionaryValue> child);
|
| +
|
| + // Creates a DictionaryValue representation of the collected information. Only
|
| + // call this once.
|
| + std::unique_ptr<base::DictionaryValue> Build();
|
| +
|
| + private:
|
| + base::DictionaryValue node_;
|
| + base::ListValue children_;
|
| + // |built_| is false until Build() is called. Once it is |true|, |node_| and
|
| + // |children_| are no longer valid for use.
|
| + bool built_ = false;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(CertNodeBuilder);
|
| +};
|
| +
|
| +CertNodeBuilder::CertNodeBuilder(base::StringPiece label) {
|
| + node_.SetString("label", label);
|
| +}
|
| +
|
| +CertNodeBuilder::CertNodeBuilder(int label_id)
|
| + : CertNodeBuilder(l10n_util::GetStringUTF8(label_id)) {}
|
| +
|
| +CertNodeBuilder& CertNodeBuilder::Payload(base::StringPiece payload) {
|
| + DCHECK(!node_.HasKey("payload.val"));
|
| + node_.SetString("payload.val", payload);
|
| + return *this;
|
| +}
|
| +
|
| +CertNodeBuilder& CertNodeBuilder::Child(
|
| + std::unique_ptr<base::DictionaryValue> child) {
|
| + children_.Append(std::move(child));
|
| + return *this;
|
| +}
|
| +
|
| +CertNodeBuilder& CertNodeBuilder::ChildIfNotNull(
|
| + std::unique_ptr<base::DictionaryValue> child) {
|
| + if (child)
|
| + return Child(std::move(child));
|
| + return *this;
|
| +}
|
| +
|
| +std::unique_ptr<base::DictionaryValue> CertNodeBuilder::Build() {
|
| + DCHECK(!built_);
|
| + if (!children_.empty()) {
|
| + node_.Set("children", base::MakeUnique<base::Value>(std::move(children_)));
|
| + }
|
| + built_ = true;
|
| + return base::MakeUnique<base::DictionaryValue>(std::move(node_));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| // Shows a certificate using the WebUI certificate viewer.
|
| void ShowCertificateViewer(WebContents* web_contents,
|
| gfx::NativeWindow parent,
|
| @@ -169,7 +250,7 @@ std::string CertificateViewerModalDialog::GetDialogArgs() const {
|
| x509_certificate_model::HashCertSHA1(cert_hnd));
|
|
|
| // Certificate hierarchy is constructed from bottom up.
|
| - base::ListValue* children = NULL;
|
| + std::unique_ptr<base::ListValue> children;
|
| int index = 0;
|
| for (net::X509Certificate::OSCertHandles::const_iterator i =
|
| cert_chain.begin(); i != cert_chain.end(); ++i, ++index) {
|
| @@ -180,14 +261,14 @@ std::string CertificateViewerModalDialog::GetDialogArgs() const {
|
| cert_node->SetDouble("payload.index", index);
|
| // Add the child from the previous iteration.
|
| if (children)
|
| - cert_node->Set("children", children);
|
| + cert_node->Set("children", std::move(children));
|
|
|
| // Add this node to the children list for the next iteration.
|
| - children = new base::ListValue();
|
| + children = base::MakeUnique<base::ListValue>();
|
| children->Append(std::move(cert_node));
|
| }
|
| // Set the last node as the top of the certificate hierarchy.
|
| - cert_info.Set("hierarchy", children);
|
| + cert_info.Set("hierarchy", std::move(children));
|
|
|
| base::JSONWriter::Write(cert_info, &data);
|
|
|
| @@ -291,181 +372,115 @@ void CertificateViewerDialogHandler::RequestCertificateFields(
|
|
|
| net::X509Certificate::OSCertHandle cert = cert_chain_[cert_index];
|
|
|
| - // Main certificate fields.
|
| - auto cert_fields = base::MakeUnique<base::ListValue>();
|
| - auto node_details = base::MakeUnique<base::DictionaryValue>();
|
| - node_details->SetString("label",
|
| - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VERSION));
|
| + CertNodeBuilder version_node(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,
|
| - base::UTF8ToUTF16(version)));
|
| + version_node.Payload(l10n_util::GetStringFUTF8(
|
| + IDS_CERT_DETAILS_VERSION_FORMAT, base::UTF8ToUTF16(version)));
|
| }
|
| - cert_fields->Append(std::move(node_details));
|
| -
|
| - node_details = base::MakeUnique<base::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(std::move(node_details));
|
| -
|
| - node_details = base::MakeUnique<base::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(std::move(node_details));
|
| -
|
| - node_details = base::MakeUnique<base::DictionaryValue>();
|
| - node_details->SetString("label",
|
| - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_ISSUER));
|
| - node_details->SetString("payload.val",
|
| - x509_certificate_model::GetIssuerName(cert));
|
| - cert_fields->Append(std::move(node_details));
|
| -
|
| - // Validity period.
|
| - auto cert_sub_fields = base::MakeUnique<base::ListValue>();
|
| -
|
| - auto sub_node_details = base::MakeUnique<base::DictionaryValue>();
|
| - sub_node_details->SetString(
|
| - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_BEFORE));
|
| -
|
| - auto alt_node_details = base::MakeUnique<base::DictionaryValue>();
|
| - alt_node_details->SetString("label",
|
| - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_AFTER));
|
|
|
| + CertNodeBuilder issued_node_builder(IDS_CERT_DETAILS_NOT_BEFORE);
|
| + CertNodeBuilder expires_node_builder(IDS_CERT_DETAILS_NOT_AFTER);
|
| base::Time issued, expires;
|
| if (x509_certificate_model::GetTimes(cert, &issued, &expires)) {
|
| - sub_node_details->SetString(
|
| - "payload.val",
|
| - base::UTF16ToUTF8(
|
| - base::TimeFormatShortDateAndTimeWithTimeZone(issued)));
|
| - alt_node_details->SetString(
|
| - "payload.val",
|
| - base::UTF16ToUTF8(
|
| - base::TimeFormatShortDateAndTimeWithTimeZone(expires)));
|
| + issued_node_builder.Payload(base::UTF16ToUTF8(
|
| + base::TimeFormatShortDateAndTimeWithTimeZone(issued)));
|
| + expires_node_builder.Payload(base::UTF16ToUTF8(
|
| + base::TimeFormatShortDateAndTimeWithTimeZone(expires)));
|
| }
|
| - cert_sub_fields->Append(std::move(sub_node_details));
|
| - cert_sub_fields->Append(std::move(alt_node_details));
|
| -
|
| - node_details = base::MakeUnique<base::DictionaryValue>();
|
| - node_details->SetString("label",
|
| - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VALIDITY));
|
| - node_details->Set("children", std::move(cert_sub_fields));
|
| - cert_fields->Append(std::move(node_details));
|
| -
|
| - node_details = base::MakeUnique<base::DictionaryValue>();
|
| - node_details->SetString("label",
|
| - l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT));
|
| - node_details->SetString("payload.val",
|
| - x509_certificate_model::GetSubjectName(cert));
|
| - cert_fields->Append(std::move(node_details));
|
| -
|
| - // Subject key information.
|
| - cert_sub_fields = base::MakeUnique<base::ListValue>();
|
| -
|
| - sub_node_details = base::MakeUnique<base::DictionaryValue>();
|
| - sub_node_details->SetString(
|
| - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_ALG));
|
| - sub_node_details->SetString(
|
| - "payload.val",
|
| - x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(cert));
|
| - cert_sub_fields->Append(std::move(sub_node_details));
|
| -
|
| - sub_node_details = base::MakeUnique<base::DictionaryValue>();
|
| - sub_node_details->SetString(
|
| - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY));
|
| - sub_node_details->SetString(
|
| - "payload.val", x509_certificate_model::ProcessSubjectPublicKeyInfo(cert));
|
| - cert_sub_fields->Append(std::move(sub_node_details));
|
| -
|
| - node_details = base::MakeUnique<base::DictionaryValue>();
|
| - node_details->SetString(
|
| - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_INFO));
|
| - node_details->Set("children", std::move(cert_sub_fields));
|
| - cert_fields->Append(std::move(node_details));
|
| -
|
| - // 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);
|
|
|
| + std::unique_ptr<base::DictionaryValue> details_extensions;
|
| if (!extensions.empty()) {
|
| - cert_sub_fields = base::MakeUnique<base::ListValue>();
|
| -
|
| - for (x509_certificate_model::Extensions::const_iterator i =
|
| - extensions.begin(); i != extensions.end(); ++i) {
|
| - sub_node_details = base::MakeUnique<base::DictionaryValue>();
|
| - sub_node_details->SetString("label", i->name);
|
| - sub_node_details->SetString("payload.val", i->value);
|
| - cert_sub_fields->Append(std::move(sub_node_details));
|
| + CertNodeBuilder details_extensions_builder(IDS_CERT_DETAILS_EXTENSIONS);
|
| + for (const x509_certificate_model::Extension& extension : extensions) {
|
| + details_extensions_builder.Child(
|
| + CertNodeBuilder(extension.name).Payload(extension.value).Build());
|
| }
|
| -
|
| - node_details = base::MakeUnique<base::DictionaryValue>();
|
| - node_details->SetString(
|
| - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_EXTENSIONS));
|
| - node_details->Set("children", std::move(cert_sub_fields));
|
| - cert_fields->Append(std::move(node_details));
|
| + details_extensions = details_extensions_builder.Build();
|
| }
|
|
|
| - // Details certificate information.
|
| - node_details = base::MakeUnique<base::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(std::move(node_details));
|
| -
|
| - node_details = base::MakeUnique<base::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(std::move(node_details));
|
| -
|
| - // Fingerprint information.
|
| - cert_sub_fields = base::MakeUnique<base::ListValue>();
|
| -
|
| - sub_node_details = base::MakeUnique<base::DictionaryValue>();
|
| - sub_node_details->SetString(
|
| - "label",
|
| - l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL));
|
| - sub_node_details->SetString("payload.val",
|
| - x509_certificate_model::HashCertSHA256(cert));
|
| - cert_sub_fields->Append(std::move(sub_node_details));
|
| -
|
| - sub_node_details = base::MakeUnique<base::DictionaryValue>();
|
| - sub_node_details->SetString(
|
| - "label", l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA1_FINGERPRINT_LABEL));
|
| - sub_node_details->SetString("payload.val",
|
| - x509_certificate_model::HashCertSHA1(cert));
|
| - cert_sub_fields->Append(std::move(sub_node_details));
|
| -
|
| - node_details = base::MakeUnique<base::DictionaryValue>();
|
| - node_details->SetString(
|
| - "label", l10n_util::GetStringUTF8(IDS_CERT_INFO_FINGERPRINTS_GROUP));
|
| - node_details->Set("children", std::move(cert_sub_fields));
|
| - cert_fields->Append(std::move(node_details));
|
| -
|
| - // Certificate information.
|
| - node_details = base::MakeUnique<base::DictionaryValue>();
|
| - node_details->SetString(
|
| - "label", l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE));
|
| - node_details->Set("children", std::move(cert_fields));
|
| - cert_fields = base::MakeUnique<base::ListValue>();
|
| - cert_fields->Append(std::move(node_details));
|
| -
|
| - // Top level information.
|
| base::ListValue root_list;
|
| - node_details = base::MakeUnique<base::DictionaryValue>();
|
| - node_details->SetString("label", x509_certificate_model::GetTitle(cert));
|
| - node_details->Set("children", std::move(cert_fields));
|
| - root_list.Append(std::move(node_details));
|
| + root_list.Append(
|
| + CertNodeBuilder(x509_certificate_model::GetTitle(cert))
|
| + .Child(
|
| + CertNodeBuilder(
|
| + l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE))
|
| + // Main certificate fields.
|
| + .Child(version_node.Build())
|
| + .Child(
|
| + CertNodeBuilder(IDS_CERT_DETAILS_SERIAL_NUMBER)
|
| + .Payload(
|
| + x509_certificate_model::GetSerialNumberHexified(
|
| + cert, l10n_util::GetStringUTF8(
|
| + IDS_CERT_INFO_FIELD_NOT_PRESENT)))
|
| + .Build())
|
| + .Child(CertNodeBuilder(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG)
|
| + .Payload(x509_certificate_model::
|
| + ProcessSecAlgorithmSignature(cert))
|
| + .Build())
|
| + .Child(
|
| + CertNodeBuilder(IDS_CERT_DETAILS_ISSUER)
|
| + .Payload(x509_certificate_model::GetIssuerName(cert))
|
| + .Build())
|
| + // Validity period.
|
| + .Child(CertNodeBuilder(IDS_CERT_DETAILS_VALIDITY)
|
| + .Child(issued_node_builder.Build())
|
| + .Child(expires_node_builder.Build())
|
| + .Build())
|
| + .Child(
|
| + CertNodeBuilder(IDS_CERT_DETAILS_SUBJECT)
|
| + .Payload(x509_certificate_model::GetSubjectName(cert))
|
| + .Build())
|
| + // Subject key information.
|
| + .Child(
|
| + CertNodeBuilder(IDS_CERT_DETAILS_SUBJECT_KEY_INFO)
|
| + .Child(
|
| + CertNodeBuilder(IDS_CERT_DETAILS_SUBJECT_KEY_ALG)
|
| + .Payload(
|
| + x509_certificate_model::
|
| + ProcessSecAlgorithmSubjectPublicKey(
|
| + cert))
|
| + .Build())
|
| + .Child(CertNodeBuilder(IDS_CERT_DETAILS_SUBJECT_KEY)
|
| + .Payload(
|
| + x509_certificate_model::
|
| + ProcessSubjectPublicKeyInfo(cert))
|
| + .Build())
|
| + .Build())
|
| + // Extensions.
|
| + .ChildIfNotNull(std::move(details_extensions))
|
| + .Child(
|
| + CertNodeBuilder(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG)
|
| + .Payload(x509_certificate_model::
|
| + ProcessSecAlgorithmSignatureWrap(cert))
|
| + .Build())
|
| + .Child(CertNodeBuilder(IDS_CERT_DETAILS_CERTIFICATE_SIG_VALUE)
|
| + .Payload(x509_certificate_model::
|
| + ProcessRawBitsSignatureWrap(cert))
|
| + .Build())
|
| + .Child(
|
| + CertNodeBuilder(IDS_CERT_INFO_FINGERPRINTS_GROUP)
|
| + .Child(CertNodeBuilder(
|
| + IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL)
|
| + .Payload(
|
| + x509_certificate_model::HashCertSHA256(
|
| + cert))
|
| + .Build())
|
| + .Child(
|
| + CertNodeBuilder(
|
| + IDS_CERT_INFO_SHA1_FINGERPRINT_LABEL)
|
| + .Payload(x509_certificate_model::HashCertSHA1(
|
| + cert))
|
| + .Build())
|
| + .Build())
|
| + .Build())
|
| + .Build());
|
|
|
| // Send certificate information to javascript.
|
| web_ui()->CallJavascriptFunctionUnsafe("cert_viewer.getCertificateFields",
|
|
|