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/views/html_dialog_view.h" | 12 #include "chrome/browser/ui/gtk/certificate_dialogs.h" |
13 #include "chrome/browser/ui/browser_dialogs.h" | 13 #include "chrome/browser/ui/browser_dialogs.h" |
14 #include "chrome/common/net/x509_certificate_model.h" | 14 #include "chrome/common/net/x509_certificate_model.h" |
| 15 #include "content/browser/tab_contents/tab_contents.h" |
15 #include "ui/base/l10n/l10n_util.h" | 16 #include "ui/base/l10n/l10n_util.h" |
16 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
20 // Default width/height of the dialog. | 21 // Default width/height of the dialog. |
21 const int kDefaultWidth = 450; | 22 const int kDefaultWidth = 450; |
22 const int kDefaultHeight = 450; | 23 const int kDefaultHeight = 450; |
23 | 24 |
24 } // namespace | 25 } // namespace |
25 | 26 |
26 // Shows a certificate using the WebUI certificate viewer. | 27 // Shows a certificate using the WebUI certificate viewer. |
27 void ShowCertificateViewer(gfx::NativeWindow parent, | 28 void ShowCertificateViewer(gfx::NativeWindow parent, |
28 net::X509Certificate* cert) { | 29 net::X509Certificate* cert) { |
29 CertificateViewerDialog::ShowDialog(parent, cert); | 30 CertificateViewerDialog::ShowDialog(parent, cert); |
30 } | 31 } |
31 | 32 |
32 void CertificateViewerDialog::ShowDialog(gfx::NativeWindow owning_window, | 33 //////////////////////////////////////////////////////////////////////////////// |
| 34 // CertificateViewerDialog |
| 35 |
| 36 void CertificateViewerDialog::ShowDialog(gfx::NativeWindow parent, |
33 net::X509Certificate* cert) { | 37 net::X509Certificate* cert) { |
34 Browser* browser = BrowserList::GetLastActive(); | 38 Browser* browser = BrowserList::GetLastActive(); |
35 DCHECK(browser); | 39 DCHECK(browser); |
36 browser->BrowserShowHtmlDialog(new CertificateViewerDialog(cert), | 40 browser->BrowserShowHtmlDialog(new CertificateViewerDialog(parent, cert), |
37 owning_window); | 41 parent); |
38 } | 42 } |
39 | 43 |
40 // TODO(flackr): This is duplicated from cookies_view_handler.cc | 44 CertificateViewerDialog::CertificateViewerDialog(gfx::NativeWindow parent, |
41 // Encodes a pointer value into a hex string. | 45 net::X509Certificate* cert) |
42 std::string PointerToHexString(const void* pointer) { | 46 : cert_(cert), parent_(parent) { |
43 return base::HexEncode(&pointer, sizeof(pointer)); | |
44 } | |
45 | |
46 CertificateViewerDialog::CertificateViewerDialog(net::X509Certificate* cert) | |
47 : 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 true; |
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(parent_, 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 gfx::NativeWindow parent, |
| 104 net::X509Certificate* cert) : cert_(cert), parent_(parent) { |
| 105 x509_certificate_model::GetCertChainFromCert(cert_->os_cert_handle(), |
| 106 &cert_chain_); |
| 107 } |
| 108 |
| 109 void CertificateViewerDialogHandler::RegisterMessages() { |
| 110 web_ui_->RegisterMessageCallback("exportCertificate", |
| 111 NewCallback(this, |
| 112 &CertificateViewerDialogHandler::ExportCertificate)); |
| 113 web_ui_->RegisterMessageCallback("requestCertificateInfo", |
| 114 NewCallback(this, |
| 115 &CertificateViewerDialogHandler::RequestCertificateInfo)); |
| 116 web_ui_->RegisterMessageCallback("requestCertificateFields", |
| 117 NewCallback(this, |
| 118 &CertificateViewerDialogHandler::RequestCertificateFields)); |
| 119 } |
| 120 |
| 121 void CertificateViewerDialogHandler::ExportCertificate( |
| 122 const base::ListValue* args) { |
| 123 int cert_index; |
| 124 double val; |
| 125 if (!(args->GetDouble(0, &val))) |
| 126 return; |
| 127 cert_index = (int)val; |
| 128 if (cert_index < 0 || cert_index >= (int)cert_chain_.size()) |
| 129 return; |
| 130 |
| 131 // TODO(flackr): We should be able to use the current dialog's container |
| 132 // window as a parent for the export dialog however chromeos builds fail |
| 133 // to locate the browser for this window. HtmlDialog should probably |
| 134 // behave similar to a window.open popup with an associated Browser |
| 135 // object. |
| 136 ShowCertExportDialog(web_ui_->tab_contents(), |
| 137 parent_, |
| 138 cert_chain_[cert_index]); |
| 139 } |
| 140 |
| 141 void CertificateViewerDialogHandler::RequestCertificateInfo( |
| 142 const base::ListValue* args) { |
| 143 // Certificate information. The keys in this dictionary's general key |
| 144 // correspond to the IDs in the Html page. |
| 145 DictionaryValue cert_info; |
| 146 net::X509Certificate::OSCertHandle cert_hnd = cert_->os_cert_handle(); |
| 147 |
| 148 // Get the certificate chain. |
| 149 net::X509Certificate::OSCertHandles cert_chain; |
| 150 x509_certificate_model::GetCertChainFromCert(cert_hnd, &cert_chain); |
| 151 |
| 152 // Certificate usage. |
| 153 std::vector<std::string> usages; |
| 154 x509_certificate_model::GetUsageStrings(cert_hnd, &usages); |
| 155 std::string usagestr; |
| 156 for (std::vector<std::string>::iterator it = usages.begin(); |
| 157 it != usages.end(); ++it) { |
| 158 if (usagestr.length() > 0) { |
| 159 usagestr += "\n"; |
| 160 } |
| 161 usagestr += *it; |
| 162 } |
| 163 cert_info.SetString("general.usages", usagestr); |
| 164 |
| 165 // Standard certificate details. |
| 166 const std::string alternative_text = |
| 167 l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT); |
| 168 cert_info.SetString("general.title", l10n_util::GetStringFUTF8( |
| 169 IDS_CERT_INFO_DIALOG_TITLE, UTF8ToUTF16(x509_certificate_model::GetTitle( |
| 170 cert_chain.front())))); |
| 171 |
| 172 // Issued to information. |
| 173 cert_info.SetString("general.issued-cn", |
| 174 x509_certificate_model::GetSubjectCommonName(cert_hnd, alternative_text)); |
| 175 cert_info.SetString("general.issued-o", |
| 176 x509_certificate_model::GetSubjectOrgName(cert_hnd, alternative_text)); |
| 177 cert_info.SetString("general.issued-ou", |
| 178 x509_certificate_model::GetSubjectOrgUnitName(cert_hnd, |
| 179 alternative_text)); |
| 180 cert_info.SetString("general.issued-sn", |
| 181 x509_certificate_model::GetSerialNumberHexified(cert_hnd, |
| 182 alternative_text)); |
| 183 |
| 184 // Issuer information. |
| 185 cert_info.SetString("general.issuer-cn", |
| 186 x509_certificate_model::GetIssuerCommonName(cert_hnd, alternative_text)); |
| 187 cert_info.SetString("general.issuer-o", |
| 188 x509_certificate_model::GetIssuerOrgName(cert_hnd, alternative_text)); |
| 189 cert_info.SetString("general.issuer-ou", |
| 190 x509_certificate_model::GetIssuerOrgUnitName(cert_hnd, alternative_text)); |
| 191 |
| 192 // Validity period. |
| 193 base::Time issued, expires; |
| 194 std::string issued_str, expires_str; |
| 195 if (x509_certificate_model::GetTimes(cert_hnd, &issued, &expires)) { |
| 196 issued_str = UTF16ToUTF8( |
| 197 base::TimeFormatShortDateNumeric(issued)); |
| 198 expires_str = UTF16ToUTF8( |
| 199 base::TimeFormatShortDateNumeric(expires)); |
| 200 } else { |
| 201 issued_str = alternative_text; |
| 202 expires_str = alternative_text; |
| 203 } |
| 204 cert_info.SetString("general.issue-date", issued_str); |
| 205 cert_info.SetString("general.expiry-date", expires_str); |
| 206 |
| 207 cert_info.SetString("general.sha256", |
| 208 x509_certificate_model::HashCertSHA256(cert_hnd)); |
| 209 cert_info.SetString("general.sha1", |
| 210 x509_certificate_model::HashCertSHA1(cert_hnd)); |
| 211 |
| 212 // Certificate hierarchy is constructed from bottom up. |
| 213 ListValue* children = NULL; |
| 214 int index = 0; |
| 215 for (net::X509Certificate::OSCertHandles::const_iterator i = |
| 216 cert_chain.begin(); i != cert_chain.end(); ++i, ++index) { |
| 217 DictionaryValue* cert_node = new DictionaryValue(); |
| 218 ListValue cert_details; |
| 219 cert_node->SetString("label", x509_certificate_model::GetTitle(*i).c_str()); |
| 220 cert_node->SetDouble("payload.index", index); |
| 221 // Add the child from the previous iteration. |
| 222 if (children) |
| 223 cert_node->Set("children", children); |
| 224 |
| 225 // Add this node to the children list for the next iteration. |
| 226 children = new ListValue(); |
| 227 children->Append(cert_node); |
| 228 } |
| 229 // Set the last node as the top of the certificate hierarchy. |
| 230 cert_info.Set("hierarchy", children); |
| 231 |
| 232 // Send certificate information to javascript. |
| 233 web_ui_->CallJavascriptFunction("cert_viewer.getCertificateInfo", cert_info); |
| 234 } |
| 235 |
| 236 void CertificateViewerDialogHandler::RequestCertificateFields( |
| 237 const base::ListValue* args) { |
| 238 int cert_index; |
| 239 double val; |
| 240 if (!(args->GetDouble(0, &val))) |
| 241 return; |
| 242 cert_index = (int)val; |
| 243 if (cert_index < 0 || cert_index >= (int)cert_chain_.size()) |
| 244 return; |
| 245 net::X509Certificate::OSCertHandle cert = cert_chain_[cert_index]; |
| 246 |
| 247 ListValue root_list; |
| 248 DictionaryValue* node_details; |
| 249 DictionaryValue* alt_node_details; |
| 250 ListValue* cert_sub_fields; |
| 251 root_list.Append(node_details = new DictionaryValue()); |
| 252 node_details->SetString("label", x509_certificate_model::GetTitle(cert)); |
| 253 |
| 254 ListValue* cert_fields; |
| 255 node_details->Set("children", cert_fields = new ListValue()); |
| 256 cert_fields->Append(node_details = new DictionaryValue()); |
| 257 |
| 258 node_details->SetString("label", |
| 259 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE)); |
| 260 node_details->Set("children", cert_fields = new ListValue()); |
| 261 |
| 262 // Main certificate fields. |
| 263 cert_fields->Append(node_details = new DictionaryValue()); |
| 264 node_details->SetString("label", |
| 265 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VERSION)); |
| 266 std::string version = x509_certificate_model::GetVersion(cert); |
| 267 if (!version.empty()) |
| 268 node_details->SetString("payload.val", |
| 269 l10n_util::GetStringFUTF8(IDS_CERT_DETAILS_VERSION_FORMAT, |
| 270 UTF8ToUTF16(version))); |
| 271 |
| 272 cert_fields->Append(node_details = new DictionaryValue()); |
| 273 node_details->SetString("label", |
| 274 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SERIAL_NUMBER)); |
| 275 node_details->SetString("payload.val", |
| 276 x509_certificate_model::GetSerialNumberHexified(cert, |
| 277 l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT))); |
| 278 |
| 279 cert_fields->Append(node_details = new DictionaryValue()); |
| 280 node_details->SetString("label", |
| 281 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG)); |
| 282 node_details->SetString("payload.val", |
| 283 x509_certificate_model::ProcessSecAlgorithmSignature(cert)); |
| 284 |
| 285 cert_fields->Append(node_details = new DictionaryValue()); |
| 286 node_details->SetString("label", |
| 287 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_ISSUER)); |
| 288 node_details->SetString("payload.val", |
| 289 x509_certificate_model::GetIssuerName(cert)); |
| 290 |
| 291 // Validity period. |
| 292 cert_fields->Append(node_details = new DictionaryValue()); |
| 293 node_details->SetString("label", |
| 294 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_VALIDITY)); |
| 295 |
| 296 node_details->Set("children", cert_sub_fields = new ListValue()); |
| 297 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 298 node_details->SetString("label", |
| 299 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_BEFORE)); |
| 300 cert_sub_fields->Append(alt_node_details = new DictionaryValue()); |
| 301 alt_node_details->SetString("label", |
| 302 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_NOT_AFTER)); |
| 303 base::Time issued, expires; |
| 304 if (x509_certificate_model::GetTimes(cert, &issued, &expires)) { |
| 305 node_details->SetString("payload.val", |
| 306 UTF16ToUTF8(base::TimeFormatShortDateAndTime(issued))); |
| 307 alt_node_details->SetString("payload.val", |
| 308 UTF16ToUTF8(base::TimeFormatShortDateAndTime(expires))); |
| 309 } |
| 310 |
| 311 cert_fields->Append(node_details = new DictionaryValue()); |
| 312 node_details->SetString("label", |
| 313 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT)); |
| 314 node_details->SetString("payload.val", |
| 315 x509_certificate_model::GetSubjectName(cert)); |
| 316 |
| 317 // Subject key information. |
| 318 cert_fields->Append(node_details = new DictionaryValue()); |
| 319 node_details->SetString("label", |
| 320 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_INFO)); |
| 321 |
| 322 node_details->Set("children", cert_sub_fields = new ListValue()); |
| 323 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 324 node_details->SetString("label", |
| 325 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY_ALG)); |
| 326 node_details->SetString("payload.val", |
| 327 x509_certificate_model::ProcessSecAlgorithmSubjectPublicKey(cert)); |
| 328 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 329 node_details->SetString("label", |
| 330 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT_KEY)); |
| 331 node_details->SetString("payload.val", |
| 332 x509_certificate_model::ProcessSubjectPublicKeyInfo(cert)); |
| 333 |
| 334 // Extensions. |
| 335 x509_certificate_model::Extensions extensions; |
| 336 x509_certificate_model::GetExtensions( |
| 337 l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_CRITICAL), |
| 338 l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_NON_CRITICAL), |
| 339 cert, &extensions); |
| 340 |
| 341 if (!extensions.empty()) { |
| 342 cert_fields->Append(node_details = new DictionaryValue()); |
| 343 node_details->SetString("label", |
| 344 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_EXTENSIONS)); |
| 345 |
| 346 node_details->Set("children", cert_sub_fields = new ListValue()); |
| 347 for (x509_certificate_model::Extensions::const_iterator i = |
| 348 extensions.begin(); i != extensions.end(); ++i) { |
| 349 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 350 node_details->SetString("label", i->name); |
| 351 node_details->SetString("payload.val", i->value); |
| 352 } |
| 353 } |
| 354 |
| 355 cert_fields->Append(node_details = new DictionaryValue()); |
| 356 node_details->SetString("label", |
| 357 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_ALG)); |
| 358 node_details->SetString("payload.val", |
| 359 x509_certificate_model::ProcessSecAlgorithmSignatureWrap(cert)); |
| 360 |
| 361 cert_fields->Append(node_details = new DictionaryValue()); |
| 362 node_details->SetString("label", |
| 363 l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_VALUE)); |
| 364 node_details->SetString("payload.val", |
| 365 x509_certificate_model::ProcessRawBitsSignatureWrap(cert)); |
| 366 |
| 367 cert_fields->Append(node_details = new DictionaryValue()); |
| 368 node_details->SetString("label", |
| 369 l10n_util::GetStringUTF8(IDS_CERT_INFO_FINGERPRINTS_GROUP)); |
| 370 node_details->Set("children", cert_sub_fields = new ListValue()); |
| 371 |
| 372 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 373 node_details->SetString("label", |
| 374 l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA256_FINGERPRINT_LABEL)); |
| 375 node_details->SetString("payload.val", |
| 376 x509_certificate_model::HashCertSHA256(cert)); |
| 377 cert_sub_fields->Append(node_details = new DictionaryValue()); |
| 378 node_details->SetString("label", |
| 379 l10n_util::GetStringUTF8(IDS_CERT_INFO_SHA1_FINGERPRINT_LABEL)); |
| 380 node_details->SetString("payload.val", |
| 381 x509_certificate_model::HashCertSHA1(cert)); |
| 382 |
| 383 // Send certificate information to javascript. |
| 384 web_ui_->CallJavascriptFunction("cert_viewer.getCertificateFields", |
| 385 root_list); |
| 386 } |
OLD | NEW |