OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/json/json_writer.h" | 5 #include "base/i18n/time_formatting.h" |
6 #include "base/utf_string_conversions.h" | 6 #include "base/utf_string_conversions.h" |
7 #include "base/string_number_conversions.h" | 7 #include "base/string_number_conversions.h" |
8 #include "chrome/browser/ui/webui/certificate_viewer.h" | 8 #include "chrome/browser/ui/webui/certificate_viewer.h" |
9 #include "chrome/common/url_constants.h" | 9 #include "chrome/common/url_constants.h" |
10 #include "chrome/browser/ui/browser.h" | 10 #include "chrome/browser/ui/browser.h" |
11 #include "chrome/browser/ui/browser_list.h" | 11 #include "chrome/browser/ui/browser_list.h" |
| 12 #include "chrome/browser/ui/gtk/certificate_dialogs.h" |
12 #include "chrome/browser/ui/views/html_dialog_view.h" | 13 #include "chrome/browser/ui/views/html_dialog_view.h" |
13 #include "chrome/browser/ui/browser_dialogs.h" | 14 #include "chrome/browser/ui/browser_dialogs.h" |
14 #include "chrome/common/net/x509_certificate_model.h" | 15 #include "chrome/common/net/x509_certificate_model.h" |
| 16 #include "content/browser/tab_contents/tab_contents.h" |
15 #include "ui/base/l10n/l10n_util.h" | 17 #include "ui/base/l10n/l10n_util.h" |
16 #include "grit/generated_resources.h" | 18 #include "grit/generated_resources.h" |
17 | 19 |
18 namespace { | 20 namespace { |
19 | 21 |
20 // Default width/height of the dialog. | 22 // Default width/height of the dialog. |
21 const int kDefaultWidth = 450; | 23 const int kDefaultWidth = 450; |
22 const int kDefaultHeight = 450; | 24 const int kDefaultHeight = 450; |
23 | 25 |
24 } // namespace | 26 } // namespace |
25 | 27 |
26 // Shows a certificate using the WebUI certificate viewer. | 28 // Shows a certificate using the WebUI certificate viewer. |
27 void ShowCertificateViewer(gfx::NativeWindow parent, | 29 void ShowCertificateViewer(gfx::NativeWindow parent, |
28 net::X509Certificate* cert) { | 30 net::X509Certificate* cert) { |
29 CertificateViewerDialog::ShowDialog(parent, cert); | 31 CertificateViewerDialog::ShowDialog(parent, cert); |
30 } | 32 } |
31 | 33 |
| 34 //////////////////////////////////////////////////////////////////////////////// |
| 35 // CertificateViewerDialog |
| 36 |
32 void CertificateViewerDialog::ShowDialog(gfx::NativeWindow owning_window, | 37 void CertificateViewerDialog::ShowDialog(gfx::NativeWindow owning_window, |
33 net::X509Certificate* cert) { | 38 net::X509Certificate* cert) { |
34 Browser* browser = BrowserList::GetLastActive(); | 39 Browser* browser = BrowserList::GetLastActive(); |
35 DCHECK(browser); | 40 DCHECK(browser); |
36 browser->BrowserShowHtmlDialog(new CertificateViewerDialog(cert), | 41 browser->BrowserShowHtmlDialog(new CertificateViewerDialog(cert), |
37 owning_window); | 42 owning_window); |
38 } | 43 } |
39 | 44 |
40 // TODO(flackr): This is duplicated from cookies_view_handler.cc | |
41 // Encodes a pointer value into a hex string. | |
42 std::string PointerToHexString(const void* pointer) { | |
43 return base::HexEncode(&pointer, sizeof(pointer)); | |
44 } | |
45 | |
46 CertificateViewerDialog::CertificateViewerDialog(net::X509Certificate* cert) | 45 CertificateViewerDialog::CertificateViewerDialog(net::X509Certificate* cert) |
47 : cert_(cert) { | 46 : cert_(cert) { |
48 // Construct the JSON string with a pointer to the stored certificate. | |
49 DictionaryValue args; | |
50 args.SetString("cert", PointerToHexString(cert_)); | |
51 base::JSONWriter::Write(&args, false, &json_args_); | |
52 | |
53 // Construct the dialog title from the certificate. | 47 // Construct the dialog title from the certificate. |
54 net::X509Certificate::OSCertHandles cert_chain; | 48 net::X509Certificate::OSCertHandles cert_chain; |
55 x509_certificate_model::GetCertChainFromCert(cert_->os_cert_handle(), | 49 x509_certificate_model::GetCertChainFromCert(cert_->os_cert_handle(), |
56 &cert_chain); | 50 &cert_chain); |
57 title_ = l10n_util::GetStringFUTF16(IDS_CERT_INFO_DIALOG_TITLE, | 51 title_ = l10n_util::GetStringFUTF16(IDS_CERT_INFO_DIALOG_TITLE, |
58 UTF8ToUTF16(x509_certificate_model::GetTitle(cert_chain.front()))); | 52 UTF8ToUTF16(x509_certificate_model::GetTitle(cert_chain.front()))); |
59 } | 53 } |
60 | 54 |
61 bool CertificateViewerDialog::IsDialogModal() const { | 55 bool CertificateViewerDialog::IsDialogModal() const { |
62 return false; | 56 return false; |
63 } | 57 } |
64 | 58 |
65 string16 CertificateViewerDialog::GetDialogTitle() const { | 59 string16 CertificateViewerDialog::GetDialogTitle() const { |
66 return title_; | 60 return title_; |
67 } | 61 } |
68 | 62 |
69 GURL CertificateViewerDialog::GetDialogContentURL() const { | 63 GURL CertificateViewerDialog::GetDialogContentURL() const { |
70 return GURL(chrome::kChromeUICertificateViewerURL); | 64 return GURL(chrome::kChromeUICertificateViewerURL); |
71 } | 65 } |
72 | 66 |
73 void CertificateViewerDialog::GetWebUIMessageHandlers( | 67 void CertificateViewerDialog::GetWebUIMessageHandlers( |
74 std::vector<WebUIMessageHandler*>* handlers) const { | 68 std::vector<WebUIMessageHandler*>* handlers) const { |
| 69 handlers->push_back(new CertificateViewerDialogHandler(cert_)); |
75 } | 70 } |
76 | 71 |
77 void CertificateViewerDialog::GetDialogSize(gfx::Size* size) const { | 72 void CertificateViewerDialog::GetDialogSize(gfx::Size* size) const { |
78 size->SetSize(kDefaultWidth, kDefaultHeight); | 73 size->SetSize(kDefaultWidth, kDefaultHeight); |
79 } | 74 } |
80 | 75 |
81 std::string CertificateViewerDialog::GetDialogArgs() const { | 76 std::string CertificateViewerDialog::GetDialogArgs() const { |
82 return json_args_; | 77 return std::string(); |
83 } | 78 } |
84 | 79 |
85 void CertificateViewerDialog::OnDialogClosed(const std::string& json_retval) { | 80 void CertificateViewerDialog::OnDialogClosed(const std::string& json_retval) { |
86 delete this; | 81 delete this; |
87 } | 82 } |
88 | 83 |
89 void CertificateViewerDialog::OnCloseContents(TabContents* source, | 84 void CertificateViewerDialog::OnCloseContents(TabContents* source, |
90 bool* out_close_dialog) { | 85 bool* out_close_dialog) { |
91 if (out_close_dialog) | 86 if (out_close_dialog) |
92 *out_close_dialog = true; | 87 *out_close_dialog = true; |
93 } | 88 } |
94 | 89 |
95 bool CertificateViewerDialog::ShouldShowDialogTitle() const { | 90 bool CertificateViewerDialog::ShouldShowDialogTitle() const { |
96 return true; | 91 return true; |
97 } | 92 } |
98 | 93 |
99 bool CertificateViewerDialog::HandleContextMenu( | 94 bool CertificateViewerDialog::HandleContextMenu( |
100 const ContextMenuParams& params) { | 95 const ContextMenuParams& params) { |
101 return true; | 96 return true; |
102 } | 97 } |
| 98 |
| 99 //////////////////////////////////////////////////////////////////////////////// |
| 100 // CertificateViewerDialogHandler |
| 101 |
| 102 CertificateViewerDialogHandler::CertificateViewerDialogHandler( |
| 103 net::X509Certificate* cert) : cert_(cert) { |
| 104 x509_certificate_model::GetCertChainFromCert(cert_->os_cert_handle(), |
| 105 &cert_chain_); |
| 106 } |
| 107 |
| 108 void CertificateViewerDialogHandler::RegisterMessages() { |
| 109 web_ui_->RegisterMessageCallback("ExportCertificate", |
| 110 NewCallback(this, |
| 111 &CertificateViewerDialogHandler::ExportCertificate)); |
| 112 web_ui_->RegisterMessageCallback("RequestCertificateInfo", |
| 113 NewCallback(this, |
| 114 &CertificateViewerDialogHandler::RequestCertificateInfo)); |
| 115 web_ui_->RegisterMessageCallback("RequestCertificateFields", |
| 116 NewCallback(this, |
| 117 &CertificateViewerDialogHandler::RequestCertificateFields)); |
| 118 } |
| 119 |
| 120 void CertificateViewerDialogHandler::ExportCertificate( |
| 121 const base::ListValue* args) { |
| 122 int cert_index; |
| 123 double val; |
| 124 if (!(args->GetDouble(0, &val))) |
| 125 return; |
| 126 cert_index = (int)val; |
| 127 if (cert_index < 0 || cert_index >= (int)cert_chain_.size()) |
| 128 return; |
| 129 ShowCertExportDialog(web_ui_->tab_contents(), |
| 130 web_ui_->tab_contents()->GetDialogRootWindow(), |
| 131 cert_chain_[cert_index]); |
| 132 } |
| 133 |
| 134 void CertificateViewerDialogHandler::RequestCertificateInfo( |
| 135 const base::ListValue* args) { |
| 136 // Certificate information. The keys in this dictionary's general key |
| 137 // correspond to the IDs in the Html page. |
| 138 DictionaryValue cert_info; |
| 139 net::X509Certificate::OSCertHandle cert_hnd = cert_->os_cert_handle(); |
| 140 |
| 141 // Get the certificate chain. |
| 142 net::X509Certificate::OSCertHandles cert_chain; |
| 143 x509_certificate_model::GetCertChainFromCert(cert_hnd, &cert_chain); |
| 144 |
| 145 // Certificate usage. |
| 146 std::vector<std::string> usages; |
| 147 x509_certificate_model::GetUsageStrings(cert_hnd, &usages); |
| 148 std::string usagestr; |
| 149 for (std::vector<std::string>::iterator it = usages.begin(); |
| 150 it != usages.end(); ++it) { |
| 151 if (usagestr.length() > 0) { |
| 152 usagestr += "\n"; |
| 153 } |
| 154 usagestr += *it; |
| 155 } |
| 156 cert_info.SetString("general.usages", usagestr); |
| 157 |
| 158 // Standard certificate details. |
| 159 const std::string alternative_text = |
| 160 l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT); |
| 161 cert_info.SetString("general.title", l10n_util::GetStringFUTF8( |
| 162 IDS_CERT_INFO_DIALOG_TITLE, UTF8ToUTF16(x509_certificate_model::GetTitle( |
| 163 cert_chain.front())))); |
| 164 |
| 165 // Issued to information. |
| 166 cert_info.SetString("general.issued-cn", |
| 167 x509_certificate_model::GetSubjectCommonName(cert_hnd, alternative_text)); |
| 168 cert_info.SetString("general.issued-o", |
| 169 x509_certificate_model::GetSubjectOrgName(cert_hnd, alternative_text)); |
| 170 cert_info.SetString("general.issued-ou", |
| 171 x509_certificate_model::GetSubjectOrgUnitName(cert_hnd, |
| 172 alternative_text)); |
| 173 cert_info.SetString("general.issued-sn", |
| 174 x509_certificate_model::GetSerialNumberHexified(cert_hnd, |
| 175 alternative_text)); |
| 176 |
| 177 // Issuer information. |
| 178 cert_info.SetString("general.issuer-cn", |
| 179 x509_certificate_model::GetIssuerCommonName(cert_hnd, alternative_text)); |
| 180 cert_info.SetString("general.issuer-o", |
| 181 x509_certificate_model::GetIssuerOrgName(cert_hnd, alternative_text)); |
| 182 cert_info.SetString("general.issuer-ou", |
| 183 x509_certificate_model::GetIssuerOrgUnitName(cert_hnd, alternative_text)); |
| 184 |
| 185 // Validity period. |
| 186 base::Time issued, expires; |
| 187 std::string issued_str, expires_str; |
| 188 if (x509_certificate_model::GetTimes(cert_hnd, &issued, &expires)) { |
| 189 issued_str = UTF16ToUTF8( |
| 190 base::TimeFormatShortDateNumeric(issued)); |
| 191 expires_str = UTF16ToUTF8( |
| 192 base::TimeFormatShortDateNumeric(expires)); |
| 193 } else { |
| 194 issued_str = alternative_text; |
| 195 expires_str = alternative_text; |
| 196 } |
| 197 cert_info.SetString("general.issue-date", issued_str); |
| 198 cert_info.SetString("general.expiry-date", expires_str); |
| 199 |
| 200 cert_info.SetString("general.sha256", |
| 201 x509_certificate_model::HashCertSHA256(cert_hnd)); |
| 202 cert_info.SetString("general.sha1", |
| 203 x509_certificate_model::HashCertSHA1(cert_hnd)); |
| 204 |
| 205 // Certificate hierarchy is constructed from bottom up. |
| 206 ListValue* children = NULL; |
| 207 int index = 0; |
| 208 for (net::X509Certificate::OSCertHandles::const_iterator i = |
| 209 cert_chain.begin(); i != cert_chain.end(); ++i, ++index) { |
| 210 DictionaryValue* cert_node = new DictionaryValue(); |
| 211 ListValue cert_details; |
| 212 cert_node->SetString("label", x509_certificate_model::GetTitle(*i).c_str()); |
| 213 cert_node->SetDouble("payload.index", index); |
| 214 // Add the child from the previous iteration. |
| 215 if (children) |
| 216 cert_node->Set("children", children); |
| 217 |
| 218 // Add this node to the children list for the next iteration. |
| 219 children = new ListValue(); |
| 220 children->Append(cert_node); |
| 221 } |
| 222 // Set the last node as the top of the certificate hierarchy. |
| 223 cert_info.Set("hierarchy", children); |
| 224 |
| 225 // Send certificate information to javascript. |
| 226 web_ui_->CallJavascriptFunction("cert_viewer.getCertificateInfo", cert_info); |
| 227 } |
| 228 |
| 229 void CertificateViewerDialogHandler::RequestCertificateFields( |
| 230 const base::ListValue* args) { |
| 231 int cert_index; |
| 232 double val; |
| 233 if (!(args->GetDouble(0, &val))) |
| 234 return; |
| 235 cert_index = (int)val; |
| 236 if (cert_index < 0 || cert_index >= (int)cert_chain_.size()) |
| 237 return; |
| 238 net::X509Certificate::OSCertHandle cert = cert_chain_[cert_index]; |
| 239 |
| 240 ListValue root_list; |
| 241 DictionaryValue* node_details; |
| 242 DictionaryValue* alt_node_details; |
| 243 ListValue* cert_sub_fields; |
| 244 root_list.Append(node_details = new DictionaryValue()); |
| 245 node_details->SetString("label", x509_certificate_model::GetTitle(cert)); |
| 246 |
| 247 ListValue* cert_fields; |
| 248 node_details->Set("children", cert_fields = new ListValue()); |
| 249 cert_fields->Append(node_details = new DictionaryValue()); |
| 250 |
| 251 node_details->SetString("label", |
| 252 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE)); |
| 253 node_details->Set("children", cert_fields = new ListValue()); |
| 254 |
| 255 // Main certificate fields. |
| 256 cert_fields->Append(node_details = new DictionaryValue()); |
| 257 node_details->SetString("label", |
| 258 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VERSION)); |
| 259 std::string version = x509_certificate_model::GetVersion(cert); |
| 260 if (!version.empty()) |
| 261 node_details->SetString("payload.val", |
| 262 l10n_util::GetStringFUTF8(IDS_CERT_DETAILS_VERSION_FORMAT, |
| 263 UTF8ToUTF16(version))); |
| 264 |
| 265 cert_fields->Append(node_details = new DictionaryValue()); |
| 266 node_details->SetString("label", |
| 267 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SERIAL_NUMBER)); |
| 268 node_details->SetString("payload.val", |
| 269 x509_certificate_model::GetSerialNumberHexified(cert, |
| 270 l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT))); |
| 271 |
| 272 cert_fields->Append(node_details = new DictionaryValue()); |
| 273 node_details->SetString("label", |
| 274 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG)); |
| 275 node_details->SetString("payload.val", |
| 276 x509_certificate_model::ProcessSecAlgorithmSignature(cert)); |
| 277 |
| 278 cert_fields->Append(node_details = new DictionaryValue()); |
| 279 node_details->SetString("label", |
| 280 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_ISSUER)); |
| 281 node_details->SetString("payload.val", |
| 282 x509_certificate_model::GetIssuerName(cert)); |
| 283 |
| 284 // Validity period. |
| 285 cert_fields->Append(node_details = new DictionaryValue()); |
| 286 node_details->SetString("label", |
| 287 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VALIDITY)); |
| 288 |
| 289 node_details->Set("children", cert_sub_fields = new ListValue()); |
| 290 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 291 node_details->SetString("label", |
| 292 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_BEFORE)); |
| 293 cert_sub_fields->Append(alt_node_details = new DictionaryValue()); |
| 294 alt_node_details->SetString("label", |
| 295 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_AFTER)); |
| 296 base::Time issued, expires; |
| 297 if (x509_certificate_model::GetTimes(cert, &issued, &expires)) { |
| 298 node_details->SetString("payload.val", |
| 299 UTF16ToUTF8(base::TimeFormatShortDateAndTime(issued))); |
| 300 alt_node_details->SetString("payload.val", |
| 301 UTF16ToUTF8(base::TimeFormatShortDateAndTime(expires))); |
| 302 } |
| 303 |
| 304 cert_fields->Append(node_details = new DictionaryValue()); |
| 305 node_details->SetString("label", |
| 306 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT)); |
| 307 node_details->SetString("payload.val", |
| 308 x509_certificate_model::GetSubjectName(cert)); |
| 309 |
| 310 // Subject key information. |
| 311 cert_fields->Append(node_details = new DictionaryValue()); |
| 312 node_details->SetString("label", |
| 313 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_INFO)); |
| 314 |
| 315 node_details->Set("children", cert_sub_fields = new ListValue()); |
| 316 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 317 node_details->SetString("label", |
| 318 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_ALG)); |
| 319 node_details->SetString("payload.val", |
| 320 x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(cert)); |
| 321 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 322 node_details->SetString("label", |
| 323 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY)); |
| 324 node_details->SetString("payload.val", |
| 325 x509_certificate_model::ProcessSubjectPublicKeyInfo(cert)); |
| 326 |
| 327 // Extensions. |
| 328 x509_certificate_model::Extensions extensions; |
| 329 x509_certificate_model::GetExtensions( |
| 330 l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_CRITICAL), |
| 331 l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_NON_CRITICAL), |
| 332 cert, &extensions); |
| 333 |
| 334 if (!extensions.empty()) { |
| 335 cert_fields->Append(node_details = new DictionaryValue()); |
| 336 node_details->SetString("label", |
| 337 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_EXTENSIONS)); |
| 338 |
| 339 node_details->Set("children", cert_sub_fields = new ListValue()); |
| 340 for (x509_certificate_model::Extensions::const_iterator i = |
| 341 extensions.begin(); i != extensions.end(); ++i) { |
| 342 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 343 node_details->SetString("label", i->name); |
| 344 node_details->SetString("payload.val", i->value); |
| 345 } |
| 346 } |
| 347 |
| 348 cert_fields->Append(node_details = new DictionaryValue()); |
| 349 node_details->SetString("label", |
| 350 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG)); |
| 351 node_details->SetString("payload.val", |
| 352 x509_certificate_model::ProcessSecAlgorithmSignatureWrap(cert)); |
| 353 |
| 354 cert_fields->Append(node_details = new DictionaryValue()); |
| 355 node_details->SetString("label", |
| 356 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_VALUE)); |
| 357 node_details->SetString("payload.val", |
| 358 x509_certificate_model::ProcessRawBitsSignatureWrap(cert)); |
| 359 |
| 360 cert_fields->Append(node_details = new DictionaryValue()); |
| 361 node_details->SetString("label", |
| 362 l10n_util::GetStringUTF8(IDS_CERT_INFO_FINGERPRINTS_GROUP)); |
| 363 node_details->Set("children", cert_sub_fields = new ListValue()); |
| 364 |
| 365 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 366 node_details->SetString("label", |
| 367 l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL)); |
| 368 node_details->SetString("payload.val", |
| 369 x509_certificate_model::HashCertSHA256(cert)); |
| 370 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 371 node_details->SetString("label", |
| 372 l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA1_FINGERPRINT_LABEL)); |
| 373 node_details->SetString("payload.val", |
| 374 x509_certificate_model::HashCertSHA1(cert)); |
| 375 |
| 376 // Send certificate information to javascript. |
| 377 web_ui_->CallJavascriptFunction("cert_viewer.getCertificateFields", |
| 378 root_list); |
| 379 } |
OLD | NEW |