Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(570)

Side by Side Diff: chrome/browser/ui/webui/options/certificate_manager_handler.cc

Issue 9814030: get rid of old options pages (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more fixes Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/options/certificate_manager_handler.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/file_util.h" // for FileAccessProvider
10 #include "base/memory/scoped_vector.h"
11 #include "base/safe_strerror_posix.h"
12 #include "base/string_number_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/certificate_viewer.h"
16 #include "chrome/browser/ui/certificate_dialogs.h"
17 #include "chrome/browser/ui/crypto_module_password_dialog.h"
18 #include "content/public/browser/browser_thread.h" // for FileAccessProvider
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_view.h"
21 #include "grit/generated_resources.h"
22 #include "net/base/crypto_module.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/x509_certificate.h"
25 #include "ui/base/l10n/l10n_util.h"
26 #include "ui/base/l10n/l10n_util_collator.h"
27
28 #if defined(OS_CHROMEOS)
29 #include "chrome/browser/chromeos/dbus/cryptohome_client.h"
30 #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
31 #endif
32
33 using content::BrowserThread;
34
35 namespace {
36
37 static const char kKeyId[] = "id";
38 static const char kSubNodesId[] = "subnodes";
39 static const char kNameId[] = "name";
40 static const char kReadOnlyId[] = "readonly";
41 static const char kUntrustedId[] = "untrusted";
42 static const char kSecurityDeviceId[] = "device";
43 static const char kErrorId[] = "error";
44
45 // Enumeration of different callers of SelectFile. (Start counting at 1 so
46 // if SelectFile is accidentally called with params=NULL it won't match any.)
47 enum {
48 EXPORT_PERSONAL_FILE_SELECTED = 1,
49 IMPORT_PERSONAL_FILE_SELECTED,
50 IMPORT_SERVER_FILE_SELECTED,
51 IMPORT_CA_FILE_SELECTED,
52 };
53
54 // TODO(mattm): These are duplicated from cookies_view_handler.cc
55 // Encodes a pointer value into a hex string.
56 std::string PointerToHexString(const void* pointer) {
57 return base::HexEncode(&pointer, sizeof(pointer));
58 }
59
60 // Decodes a pointer from a hex string.
61 void* HexStringToPointer(const std::string& str) {
62 std::vector<uint8> buffer;
63 if (!base::HexStringToBytes(str, &buffer) ||
64 buffer.size() != sizeof(void*)) {
65 return NULL;
66 }
67
68 return *reinterpret_cast<void**>(&buffer[0]);
69 }
70
71 std::string OrgNameToId(const std::string& org) {
72 return "org-" + org;
73 }
74
75 std::string CertToId(const net::X509Certificate& cert) {
76 return "cert-" + PointerToHexString(&cert);
77 }
78
79 net::X509Certificate* IdToCert(const std::string& id) {
80 if (!StartsWithASCII(id, "cert-", true))
81 return NULL;
82 return reinterpret_cast<net::X509Certificate*>(
83 HexStringToPointer(id.substr(5)));
84 }
85
86 net::X509Certificate* CallbackArgsToCert(const ListValue* args) {
87 std::string node_id;
88 if (!args->GetString(0, &node_id)){
89 return NULL;
90 }
91 net::X509Certificate* cert = IdToCert(node_id);
92 if (!cert) {
93 NOTREACHED();
94 return NULL;
95 }
96 return cert;
97 }
98
99 bool CallbackArgsToBool(const ListValue* args, int index, bool* result) {
100 std::string string_value;
101 if (!args->GetString(index, &string_value))
102 return false;
103
104 *result = string_value[0] == 't';
105 return true;
106 }
107
108 struct DictionaryIdComparator {
109 explicit DictionaryIdComparator(icu::Collator* collator)
110 : collator_(collator) {
111 }
112
113 bool operator()(const Value* a,
114 const Value* b) const {
115 DCHECK(a->GetType() == Value::TYPE_DICTIONARY);
116 DCHECK(b->GetType() == Value::TYPE_DICTIONARY);
117 const DictionaryValue* a_dict = reinterpret_cast<const DictionaryValue*>(a);
118 const DictionaryValue* b_dict = reinterpret_cast<const DictionaryValue*>(b);
119 string16 a_str;
120 string16 b_str;
121 a_dict->GetString(kNameId, &a_str);
122 b_dict->GetString(kNameId, &b_str);
123 if (collator_ == NULL)
124 return a_str < b_str;
125 return l10n_util::CompareString16WithCollator(
126 collator_, a_str, b_str) == UCOL_LESS;
127 }
128
129 icu::Collator* collator_;
130 };
131
132 std::string NetErrorToString(int net_error) {
133 switch (net_error) {
134 // TODO(mattm): handle more cases.
135 case net::ERR_IMPORT_CA_CERT_NOT_CA:
136 return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_ERROR_NOT_CA);
137 default:
138 return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR);
139 }
140 }
141
142 } // namespace
143
144 ///////////////////////////////////////////////////////////////////////////////
145 // FileAccessProvider
146
147 // TODO(mattm): Move to some shared location?
148 class FileAccessProvider
149 : public base::RefCountedThreadSafe<FileAccessProvider>,
150 public CancelableRequestProvider {
151 public:
152 // Reports 0 on success or errno on failure, and the data of the file upon
153 // success.
154 // TODO(mattm): don't pass std::string by value.. could use RefCountedBytes
155 // but it's a vector. Maybe do the derive from CancelableRequest thing
156 // described in cancelable_request.h?
157 typedef base::Callback<void(int, std::string)> ReadCallback;
158
159 // Reports 0 on success or errno on failure, and the number of bytes written,
160 // on success.
161 typedef base::Callback<void(int, int)> WriteCallback;
162
163 Handle StartRead(const FilePath& path,
164 CancelableRequestConsumerBase* consumer,
165 const ReadCallback& callback);
166 Handle StartWrite(const FilePath& path,
167 const std::string& data,
168 CancelableRequestConsumerBase* consumer,
169 const WriteCallback& callback);
170
171 private:
172 void DoRead(scoped_refptr<CancelableRequest<ReadCallback> > request,
173 FilePath path);
174 void DoWrite(scoped_refptr<CancelableRequest<WriteCallback> > request,
175 FilePath path,
176 std::string data);
177 };
178
179 CancelableRequestProvider::Handle FileAccessProvider::StartRead(
180 const FilePath& path,
181 CancelableRequestConsumerBase* consumer,
182 const ReadCallback& callback) {
183 scoped_refptr<CancelableRequest<ReadCallback> > request(
184 new CancelableRequest<ReadCallback>(callback));
185 AddRequest(request, consumer);
186
187 // Send the parameters and the request to the file thread.
188 BrowserThread::PostTask(
189 BrowserThread::FILE, FROM_HERE,
190 base::Bind(&FileAccessProvider::DoRead, this, request, path));
191
192 // The handle will have been set by AddRequest.
193 return request->handle();
194 }
195
196 CancelableRequestProvider::Handle FileAccessProvider::StartWrite(
197 const FilePath& path,
198 const std::string& data,
199 CancelableRequestConsumerBase* consumer,
200 const WriteCallback& callback) {
201 scoped_refptr<CancelableRequest<WriteCallback> > request(
202 new CancelableRequest<WriteCallback>(callback));
203 AddRequest(request, consumer);
204
205 // Send the parameters and the request to the file thWrite.
206 BrowserThread::PostTask(
207 BrowserThread::FILE, FROM_HERE,
208 base::Bind(&FileAccessProvider::DoWrite, this, request, path, data));
209
210 // The handle will have been set by AddRequest.
211 return request->handle();
212 }
213
214 void FileAccessProvider::DoRead(
215 scoped_refptr<CancelableRequest<ReadCallback> > request,
216 FilePath path) {
217 if (request->canceled())
218 return;
219
220 std::string data;
221 VLOG(1) << "DoRead starting read";
222 bool success = file_util::ReadFileToString(path, &data);
223 int saved_errno = success ? 0 : errno;
224 VLOG(1) << "DoRead done read: " << success << " " << data.size();
225 request->ForwardResult(saved_errno, data);
226 }
227
228 void FileAccessProvider::DoWrite(
229 scoped_refptr<CancelableRequest<WriteCallback> > request,
230 FilePath path,
231 std::string data) {
232 VLOG(1) << "DoWrite starting write";
233 int bytes_written = file_util::WriteFile(path, data.data(), data.size());
234 int saved_errno = bytes_written >= 0 ? 0 : errno;
235 VLOG(1) << "DoWrite done write " << bytes_written;
236
237 if (request->canceled())
238 return;
239
240 request->ForwardResult(saved_errno, bytes_written);
241 }
242
243 ///////////////////////////////////////////////////////////////////////////////
244 // CertificateManagerHandler
245
246 CertificateManagerHandler::CertificateManagerHandler()
247 : file_access_provider_(new FileAccessProvider),
248 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
249 certificate_manager_model_.reset(new CertificateManagerModel(this));
250 }
251
252 CertificateManagerHandler::~CertificateManagerHandler() {
253 }
254
255 void CertificateManagerHandler::GetLocalizedValues(
256 DictionaryValue* localized_strings) {
257 DCHECK(localized_strings);
258
259 RegisterTitle(localized_strings, "certificateManagerPage",
260 IDS_CERTIFICATE_MANAGER_TITLE);
261
262 // Tabs.
263 localized_strings->SetString("personalCertsTabTitle",
264 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PERSONAL_CERTS_TAB_LABEL));
265 localized_strings->SetString("serverCertsTabTitle",
266 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_SERVER_CERTS_TAB_LABEL));
267 localized_strings->SetString("caCertsTabTitle",
268 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_CERT_AUTHORITIES_TAB_LABEL));
269 localized_strings->SetString("unknownCertsTabTitle",
270 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_UNKNOWN_TAB_LABEL));
271
272 // Tab descriptions.
273 localized_strings->SetString("personalCertsTabDescription",
274 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_USER_TREE_DESCRIPTION));
275 localized_strings->SetString("serverCertsTabDescription",
276 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_SERVER_TREE_DESCRIPTION));
277 localized_strings->SetString("caCertsTabDescription",
278 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_AUTHORITIES_TREE_DESCRIPTION));
279 localized_strings->SetString("unknownCertsTabDescription",
280 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_UNKNOWN_TREE_DESCRIPTION));
281
282 // Tree columns.
283 localized_strings->SetString("certNameColumn",
284 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_NAME_COLUMN_LABEL));
285 localized_strings->SetString("certDeviceColumn",
286 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DEVICE_COLUMN_LABEL));
287 localized_strings->SetString("certSerialColumn",
288 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_SERIAL_NUMBER_COLUMN_LABEL));
289 localized_strings->SetString("certExpiresColumn",
290 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPIRES_COLUMN_LABEL));
291
292 // Buttons.
293 localized_strings->SetString("view_certificate",
294 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_VIEW_CERT_BUTTON));
295 localized_strings->SetString("import_certificate",
296 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_BUTTON));
297 localized_strings->SetString("export_certificate",
298 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_BUTTON));
299 localized_strings->SetString("export_all_certificates",
300 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_ALL_BUTTON));
301 localized_strings->SetString("edit_certificate",
302 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_BUTTON));
303 localized_strings->SetString("delete_certificate",
304 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_BUTTON));
305
306 // Certificate Delete overlay strings.
307 localized_strings->SetString("personalCertsTabDeleteConfirm",
308 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_USER_FORMAT));
309 localized_strings->SetString("personalCertsTabDeleteImpact",
310 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_USER_DESCRIPTION));
311 localized_strings->SetString("serverCertsTabDeleteConfirm",
312 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_SERVER_FORMAT));
313 localized_strings->SetString("serverCertsTabDeleteImpact",
314 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_SERVER_DESCRIPTION));
315 localized_strings->SetString("caCertsTabDeleteConfirm",
316 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_CA_FORMAT));
317 localized_strings->SetString("caCertsTabDeleteImpact",
318 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_CA_DESCRIPTION));
319 localized_strings->SetString("unknownCertsTabDeleteConfirm",
320 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_UNKNOWN_FORMAT));
321 localized_strings->SetString("unknownCertsTabDeleteImpact", "");
322
323 // Certificate Restore overlay strings.
324 localized_strings->SetString("certificateRestorePasswordDescription",
325 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_RESTORE_PASSWORD_DESC));
326 localized_strings->SetString("certificatePasswordLabel",
327 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PASSWORD_LABEL));
328
329 // Personal Certificate Export overlay strings.
330 localized_strings->SetString("certificateExportPasswordDescription",
331 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_PASSWORD_DESC));
332 localized_strings->SetString("certificateExportPasswordHelp",
333 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_PASSWORD_HELP));
334 localized_strings->SetString("certificateConfirmPasswordLabel",
335 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_CONFIRM_PASSWORD_LABEL));
336
337 // Edit CA Trust & Import CA overlay strings.
338 localized_strings->SetString("certificateEditTrustLabel",
339 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_TRUST_LABEL));
340 localized_strings->SetString("certificateEditCaTrustDescriptionFormat",
341 l10n_util::GetStringUTF16(
342 IDS_CERT_MANAGER_EDIT_CA_TRUST_DESCRIPTION_FORMAT));
343 localized_strings->SetString("certificateImportCaDescriptionFormat",
344 l10n_util::GetStringUTF16(
345 IDS_CERT_MANAGER_IMPORT_CA_DESCRIPTION_FORMAT));
346 localized_strings->SetString("certificateCaTrustSSLLabel",
347 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_SSL_LABEL));
348 localized_strings->SetString("certificateCaTrustEmailLabel",
349 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_EMAIL_LABEL));
350 localized_strings->SetString("certificateCaTrustObjSignLabel",
351 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_OBJSIGN_LABEL));
352 localized_strings->SetString("certificateImportErrorFormat",
353 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_ERROR_FORMAT));
354
355 // Badges next to certificates
356 localized_strings->SetString("badgeCertUntrusted",
357 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_UNTRUSTED));
358
359 #if defined(OS_CHROMEOS)
360 localized_strings->SetString("importAndBindCertificate",
361 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_AND_BIND_BUTTON));
362 localized_strings->SetString("hardwareBackedKeyFormat",
363 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED_KEY_FORMAT));
364 localized_strings->SetString("chromeOSDeviceName",
365 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED));
366 #endif // defined(OS_CHROMEOS)
367 }
368
369 void CertificateManagerHandler::RegisterMessages() {
370 web_ui()->RegisterMessageCallback(
371 "viewCertificate",
372 base::Bind(&CertificateManagerHandler::View, base::Unretained(this)));
373
374 web_ui()->RegisterMessageCallback(
375 "getCaCertificateTrust",
376 base::Bind(&CertificateManagerHandler::GetCATrust,
377 base::Unretained(this)));
378 web_ui()->RegisterMessageCallback(
379 "editCaCertificateTrust",
380 base::Bind(&CertificateManagerHandler::EditCATrust,
381 base::Unretained(this)));
382
383 web_ui()->RegisterMessageCallback(
384 "editServerCertificate",
385 base::Bind(&CertificateManagerHandler::EditServer,
386 base::Unretained(this)));
387
388 web_ui()->RegisterMessageCallback(
389 "cancelImportExportCertificate",
390 base::Bind(&CertificateManagerHandler::CancelImportExportProcess,
391 base::Unretained(this)));
392
393 web_ui()->RegisterMessageCallback(
394 "exportPersonalCertificate",
395 base::Bind(&CertificateManagerHandler::ExportPersonal,
396 base::Unretained(this)));
397 web_ui()->RegisterMessageCallback(
398 "exportAllPersonalCertificates",
399 base::Bind(&CertificateManagerHandler::ExportAllPersonal,
400 base::Unretained(this)));
401 web_ui()->RegisterMessageCallback(
402 "exportPersonalCertificatePasswordSelected",
403 base::Bind(&CertificateManagerHandler::ExportPersonalPasswordSelected,
404 base::Unretained(this)));
405
406 web_ui()->RegisterMessageCallback(
407 "importPersonalCertificate",
408 base::Bind(&CertificateManagerHandler::StartImportPersonal,
409 base::Unretained(this)));
410 web_ui()->RegisterMessageCallback(
411 "importPersonalCertificatePasswordSelected",
412 base::Bind(&CertificateManagerHandler::ImportPersonalPasswordSelected,
413 base::Unretained(this)));
414
415 web_ui()->RegisterMessageCallback(
416 "importCaCertificate",
417 base::Bind(&CertificateManagerHandler::ImportCA,
418 base::Unretained(this)));
419 web_ui()->RegisterMessageCallback(
420 "importCaCertificateTrustSelected",
421 base::Bind(&CertificateManagerHandler::ImportCATrustSelected,
422 base::Unretained(this)));
423
424 web_ui()->RegisterMessageCallback(
425 "importServerCertificate",
426 base::Bind(&CertificateManagerHandler::ImportServer,
427 base::Unretained(this)));
428
429 web_ui()->RegisterMessageCallback(
430 "exportCertificate",
431 base::Bind(&CertificateManagerHandler::Export,
432 base::Unretained(this)));
433
434 web_ui()->RegisterMessageCallback(
435 "deleteCertificate",
436 base::Bind(&CertificateManagerHandler::Delete,
437 base::Unretained(this)));
438
439 web_ui()->RegisterMessageCallback(
440 "populateCertificateManager",
441 base::Bind(&CertificateManagerHandler::Populate,
442 base::Unretained(this)));
443
444 #if defined(OS_CHROMEOS)
445 web_ui()->RegisterMessageCallback(
446 "checkTpmTokenReady",
447 base::Bind(&CertificateManagerHandler::CheckTpmTokenReady,
448 base::Unretained(this)));
449 #endif
450 }
451
452 void CertificateManagerHandler::CertificatesRefreshed() {
453 PopulateTree("personalCertsTab", net::USER_CERT);
454 PopulateTree("serverCertsTab", net::SERVER_CERT);
455 PopulateTree("caCertsTab", net::CA_CERT);
456 PopulateTree("otherCertsTab", net::UNKNOWN_CERT);
457 VLOG(1) << "populating finished";
458 }
459
460 void CertificateManagerHandler::FileSelected(const FilePath& path, int index,
461 void* params) {
462 switch (reinterpret_cast<intptr_t>(params)) {
463 case EXPORT_PERSONAL_FILE_SELECTED:
464 ExportPersonalFileSelected(path);
465 break;
466 case IMPORT_PERSONAL_FILE_SELECTED:
467 ImportPersonalFileSelected(path);
468 break;
469 case IMPORT_SERVER_FILE_SELECTED:
470 ImportServerFileSelected(path);
471 break;
472 case IMPORT_CA_FILE_SELECTED:
473 ImportCAFileSelected(path);
474 break;
475 default:
476 NOTREACHED();
477 }
478 }
479
480 void CertificateManagerHandler::FileSelectionCanceled(void* params) {
481 switch (reinterpret_cast<intptr_t>(params)) {
482 case EXPORT_PERSONAL_FILE_SELECTED:
483 case IMPORT_PERSONAL_FILE_SELECTED:
484 case IMPORT_SERVER_FILE_SELECTED:
485 case IMPORT_CA_FILE_SELECTED:
486 ImportExportCleanup();
487 break;
488 default:
489 NOTREACHED();
490 }
491 }
492
493 void CertificateManagerHandler::View(const ListValue* args) {
494 net::X509Certificate* cert = CallbackArgsToCert(args);
495 if (!cert)
496 return;
497 ShowCertificateViewer(GetParentWindow(), cert);
498 }
499
500 void CertificateManagerHandler::GetCATrust(const ListValue* args) {
501 net::X509Certificate* cert = CallbackArgsToCert(args);
502 if (!cert) {
503 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
504 return;
505 }
506
507 net::CertDatabase::TrustBits trust_bits =
508 certificate_manager_model_->cert_db().GetCertTrust(cert, net::CA_CERT);
509 base::FundamentalValue ssl_value(
510 static_cast<bool>(trust_bits & net::CertDatabase::TRUSTED_SSL));
511 base::FundamentalValue email_value(
512 static_cast<bool>(trust_bits & net::CertDatabase::TRUSTED_EMAIL));
513 base::FundamentalValue obj_sign_value(
514 static_cast<bool>(trust_bits & net::CertDatabase::TRUSTED_OBJ_SIGN));
515 web_ui()->CallJavascriptFunction(
516 "CertificateEditCaTrustOverlay.populateTrust",
517 ssl_value, email_value, obj_sign_value);
518 }
519
520 void CertificateManagerHandler::EditCATrust(const ListValue* args) {
521 net::X509Certificate* cert = CallbackArgsToCert(args);
522 bool fail = !cert;
523 bool trust_ssl = false;
524 bool trust_email = false;
525 bool trust_obj_sign = false;
526 fail |= !CallbackArgsToBool(args, 1, &trust_ssl);
527 fail |= !CallbackArgsToBool(args, 2, &trust_email);
528 fail |= !CallbackArgsToBool(args, 3, &trust_obj_sign);
529 if (fail) {
530 LOG(ERROR) << "EditCATrust args fail";
531 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
532 return;
533 }
534
535 bool result = certificate_manager_model_->SetCertTrust(
536 cert,
537 net::CA_CERT,
538 trust_ssl * net::CertDatabase::TRUSTED_SSL +
539 trust_email * net::CertDatabase::TRUSTED_EMAIL +
540 trust_obj_sign * net::CertDatabase::TRUSTED_OBJ_SIGN);
541 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
542 if (!result) {
543 // TODO(mattm): better error messages?
544 ShowError(
545 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SET_TRUST_ERROR_TITLE),
546 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
547 }
548 }
549
550 void CertificateManagerHandler::EditServer(const ListValue* args) {
551 NOTIMPLEMENTED();
552 }
553
554 void CertificateManagerHandler::ExportPersonal(const ListValue* args) {
555 net::X509Certificate* cert = CallbackArgsToCert(args);
556 if (!cert)
557 return;
558
559 selected_cert_list_.push_back(cert);
560
561 SelectFileDialog::FileTypeInfo file_type_info;
562 file_type_info.extensions.resize(1);
563 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("p12"));
564 file_type_info.extension_description_overrides.push_back(
565 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PKCS12_FILES));
566 file_type_info.include_all_files = true;
567 select_file_dialog_ = SelectFileDialog::Create(this);
568 select_file_dialog_->SelectFile(
569 SelectFileDialog::SELECT_SAVEAS_FILE, string16(),
570 FilePath(), &file_type_info, 1, FILE_PATH_LITERAL("p12"),
571 web_ui()->GetWebContents(), GetParentWindow(),
572 reinterpret_cast<void*>(EXPORT_PERSONAL_FILE_SELECTED));
573 }
574
575 void CertificateManagerHandler::ExportAllPersonal(const ListValue* args) {
576 NOTIMPLEMENTED();
577 }
578
579 void CertificateManagerHandler::ExportPersonalFileSelected(
580 const FilePath& path) {
581 file_path_ = path;
582 web_ui()->CallJavascriptFunction(
583 "CertificateManager.exportPersonalAskPassword");
584 }
585
586 void CertificateManagerHandler::ExportPersonalPasswordSelected(
587 const ListValue* args) {
588 if (!args->GetString(0, &password_)){
589 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
590 ImportExportCleanup();
591 return;
592 }
593
594 // Currently, we don't support exporting more than one at a time. If we do,
595 // this would need to either change this to use UnlockSlotsIfNecessary or
596 // change UnlockCertSlotIfNecessary to take a CertificateList.
597 DCHECK_EQ(selected_cert_list_.size(), 1U);
598
599 // TODO(mattm): do something smarter about non-extractable keys
600 browser::UnlockCertSlotIfNecessary(
601 selected_cert_list_[0].get(),
602 browser::kCryptoModulePasswordCertExport,
603 "", // unused.
604 base::Bind(&CertificateManagerHandler::ExportPersonalSlotsUnlocked,
605 base::Unretained(this)));
606 }
607
608 void CertificateManagerHandler::ExportPersonalSlotsUnlocked() {
609 std::string output;
610 int num_exported = certificate_manager_model_->cert_db().ExportToPKCS12(
611 selected_cert_list_,
612 password_,
613 &output);
614 if (!num_exported) {
615 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
616 ShowError(
617 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_EXPORT_ERROR_TITLE),
618 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
619 ImportExportCleanup();
620 return;
621 }
622 file_access_provider_->StartWrite(
623 file_path_, output, &consumer_,
624 base::Bind(&CertificateManagerHandler::ExportPersonalFileWritten,
625 base::Unretained(this)));
626 }
627
628 void CertificateManagerHandler::ExportPersonalFileWritten(int write_errno,
629 int bytes_written) {
630 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
631 ImportExportCleanup();
632 if (write_errno) {
633 ShowError(
634 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_EXPORT_ERROR_TITLE),
635 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_WRITE_ERROR_FORMAT,
636 UTF8ToUTF16(safe_strerror(write_errno))));
637 }
638 }
639
640 void CertificateManagerHandler::StartImportPersonal(const ListValue* args) {
641 SelectFileDialog::FileTypeInfo file_type_info;
642 if (!args->GetBoolean(0, &use_hardware_backed_)){
643 // Unable to retrieve the hardware backed attribute from the args,
644 // so bail.
645 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
646 ImportExportCleanup();
647 return;
648 }
649 file_type_info.extensions.resize(1);
650 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("p12"));
651 file_type_info.extension_description_overrides.push_back(
652 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PKCS12_FILES));
653 file_type_info.include_all_files = true;
654 select_file_dialog_ = SelectFileDialog::Create(this);
655 select_file_dialog_->SelectFile(
656 SelectFileDialog::SELECT_OPEN_FILE, string16(),
657 FilePath(), &file_type_info, 1, FILE_PATH_LITERAL("p12"),
658 web_ui()->GetWebContents(), GetParentWindow(),
659 reinterpret_cast<void*>(IMPORT_PERSONAL_FILE_SELECTED));
660 }
661
662 void CertificateManagerHandler::ImportPersonalFileSelected(
663 const FilePath& path) {
664 file_path_ = path;
665 web_ui()->CallJavascriptFunction(
666 "CertificateManager.importPersonalAskPassword");
667 }
668
669 void CertificateManagerHandler::ImportPersonalPasswordSelected(
670 const ListValue* args) {
671 if (!args->GetString(0, &password_)){
672 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
673 ImportExportCleanup();
674 return;
675 }
676 file_access_provider_->StartRead(
677 file_path_, &consumer_,
678 base::Bind(&CertificateManagerHandler::ImportPersonalFileRead,
679 base::Unretained(this)));
680 }
681
682 void CertificateManagerHandler::ImportPersonalFileRead(
683 int read_errno, std::string data) {
684 if (read_errno) {
685 ImportExportCleanup();
686 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
687 ShowError(
688 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_IMPORT_ERROR_TITLE),
689 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT,
690 UTF8ToUTF16(safe_strerror(read_errno))));
691 return;
692 }
693
694 file_data_ = data;
695
696 if (use_hardware_backed_) {
697 module_ = certificate_manager_model_->cert_db().GetPrivateModule();
698 } else {
699 module_ = certificate_manager_model_->cert_db().GetPublicModule();
700 }
701
702 net::CryptoModuleList modules;
703 modules.push_back(module_);
704 browser::UnlockSlotsIfNecessary(
705 modules,
706 browser::kCryptoModulePasswordCertImport,
707 "", // unused.
708 base::Bind(&CertificateManagerHandler::ImportPersonalSlotUnlocked,
709 base::Unretained(this)));
710 }
711
712 void CertificateManagerHandler::ImportPersonalSlotUnlocked() {
713 // Determine if the private key should be unextractable after the import.
714 // We do this by checking the value of |use_hardware_backed_| which is set
715 // to true if importing into a hardware module. Currently, this only happens
716 // for Chrome OS when the "Import and Bind" option is chosen.
717 bool is_extractable = !use_hardware_backed_;
718 int result = certificate_manager_model_->ImportFromPKCS12(
719 module_, file_data_, password_, is_extractable);
720 ImportExportCleanup();
721 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
722 int string_id;
723 switch (result) {
724 case net::OK:
725 return;
726 case net::ERR_PKCS12_IMPORT_BAD_PASSWORD:
727 // TODO(mattm): if the error was a bad password, we should reshow the
728 // password dialog after the user dismisses the error dialog.
729 string_id = IDS_CERT_MANAGER_BAD_PASSWORD;
730 break;
731 case net::ERR_PKCS12_IMPORT_INVALID_MAC:
732 string_id = IDS_CERT_MANAGER_PKCS12_IMPORT_INVALID_MAC;
733 break;
734 case net::ERR_PKCS12_IMPORT_INVALID_FILE:
735 string_id = IDS_CERT_MANAGER_PKCS12_IMPORT_INVALID_FILE;
736 break;
737 case net::ERR_PKCS12_IMPORT_UNSUPPORTED:
738 string_id = IDS_CERT_MANAGER_PKCS12_IMPORT_UNSUPPORTED;
739 break;
740 default:
741 string_id = IDS_CERT_MANAGER_UNKNOWN_ERROR;
742 break;
743 }
744 ShowError(
745 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_IMPORT_ERROR_TITLE),
746 l10n_util::GetStringUTF8(string_id));
747 }
748
749 void CertificateManagerHandler::CancelImportExportProcess(
750 const ListValue* args) {
751 ImportExportCleanup();
752 }
753
754 void CertificateManagerHandler::ImportExportCleanup() {
755 file_path_.clear();
756 password_.clear();
757 file_data_.clear();
758 use_hardware_backed_ = false;
759 selected_cert_list_.clear();
760 module_ = NULL;
761
762 // There may be pending file dialogs, we need to tell them that we've gone
763 // away so they don't try and call back to us.
764 if (select_file_dialog_.get())
765 select_file_dialog_->ListenerDestroyed();
766 select_file_dialog_ = NULL;
767 }
768
769 void CertificateManagerHandler::ImportServer(const ListValue* args) {
770 select_file_dialog_ = SelectFileDialog::Create(this);
771 ShowCertSelectFileDialog(
772 select_file_dialog_.get(),
773 SelectFileDialog::SELECT_OPEN_FILE,
774 FilePath(),
775 web_ui()->GetWebContents(),
776 GetParentWindow(),
777 reinterpret_cast<void*>(IMPORT_SERVER_FILE_SELECTED));
778 }
779
780 void CertificateManagerHandler::ImportServerFileSelected(const FilePath& path) {
781 file_path_ = path;
782 file_access_provider_->StartRead(
783 file_path_, &consumer_,
784 base::Bind(&CertificateManagerHandler::ImportServerFileRead,
785 base::Unretained(this)));
786 }
787
788 void CertificateManagerHandler::ImportServerFileRead(int read_errno,
789 std::string data) {
790 if (read_errno) {
791 ImportExportCleanup();
792 ShowError(
793 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE),
794 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT,
795 UTF8ToUTF16(safe_strerror(read_errno))));
796 return;
797 }
798
799 selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes(
800 data.data(), data.size(), net::X509Certificate::FORMAT_AUTO);
801 if (selected_cert_list_.empty()) {
802 ImportExportCleanup();
803 ShowError(
804 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE),
805 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR));
806 return;
807 }
808
809 net::CertDatabase::ImportCertFailureList not_imported;
810 bool result = certificate_manager_model_->ImportServerCert(
811 selected_cert_list_,
812 &not_imported);
813 if (!result) {
814 ShowError(
815 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE),
816 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
817 } else if (!not_imported.empty()) {
818 ShowImportErrors(
819 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE),
820 not_imported);
821 }
822 ImportExportCleanup();
823 }
824
825 void CertificateManagerHandler::ImportCA(const ListValue* args) {
826 select_file_dialog_ = SelectFileDialog::Create(this);
827 ShowCertSelectFileDialog(select_file_dialog_.get(),
828 SelectFileDialog::SELECT_OPEN_FILE,
829 FilePath(),
830 web_ui()->GetWebContents(),
831 GetParentWindow(),
832 reinterpret_cast<void*>(IMPORT_CA_FILE_SELECTED));
833 }
834
835 void CertificateManagerHandler::ImportCAFileSelected(const FilePath& path) {
836 file_path_ = path;
837 file_access_provider_->StartRead(
838 file_path_, &consumer_,
839 base::Bind(&CertificateManagerHandler::ImportCAFileRead,
840 base::Unretained(this)));
841 }
842
843 void CertificateManagerHandler::ImportCAFileRead(int read_errno,
844 std::string data) {
845 if (read_errno) {
846 ImportExportCleanup();
847 ShowError(
848 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
849 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT,
850 UTF8ToUTF16(safe_strerror(read_errno))));
851 return;
852 }
853
854 selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes(
855 data.data(), data.size(), net::X509Certificate::FORMAT_AUTO);
856 if (selected_cert_list_.empty()) {
857 ImportExportCleanup();
858 ShowError(
859 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
860 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR));
861 return;
862 }
863
864 scoped_refptr<net::X509Certificate> root_cert =
865 certificate_manager_model_->cert_db().FindRootInList(selected_cert_list_);
866
867 // TODO(mattm): check here if root_cert is not a CA cert and show error.
868
869 StringValue cert_name(root_cert->subject().GetDisplayName());
870 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.showImport",
871 cert_name);
872 }
873
874 void CertificateManagerHandler::ImportCATrustSelected(const ListValue* args) {
875 bool fail = false;
876 bool trust_ssl = false;
877 bool trust_email = false;
878 bool trust_obj_sign = false;
879 fail |= !CallbackArgsToBool(args, 0, &trust_ssl);
880 fail |= !CallbackArgsToBool(args, 1, &trust_email);
881 fail |= !CallbackArgsToBool(args, 2, &trust_obj_sign);
882 if (fail) {
883 LOG(ERROR) << "ImportCATrustSelected args fail";
884 ImportExportCleanup();
885 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
886 return;
887 }
888
889 net::CertDatabase::ImportCertFailureList not_imported;
890 bool result = certificate_manager_model_->ImportCACerts(
891 selected_cert_list_,
892 trust_ssl * net::CertDatabase::TRUSTED_SSL +
893 trust_email * net::CertDatabase::TRUSTED_EMAIL +
894 trust_obj_sign * net::CertDatabase::TRUSTED_OBJ_SIGN,
895 &not_imported);
896 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
897 if (!result) {
898 ShowError(
899 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
900 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
901 } else if (!not_imported.empty()) {
902 ShowImportErrors(
903 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
904 not_imported);
905 }
906 ImportExportCleanup();
907 }
908
909 void CertificateManagerHandler::Export(const ListValue* args) {
910 net::X509Certificate* cert = CallbackArgsToCert(args);
911 if (!cert)
912 return;
913 ShowCertExportDialog(web_ui()->GetWebContents(), GetParentWindow(),
914 cert->os_cert_handle());
915 }
916
917 void CertificateManagerHandler::Delete(const ListValue* args) {
918 net::X509Certificate* cert = CallbackArgsToCert(args);
919 if (!cert)
920 return;
921 bool result = certificate_manager_model_->Delete(cert);
922 if (!result) {
923 // TODO(mattm): better error messages?
924 ShowError(
925 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_DELETE_CERT_ERROR_TITLE),
926 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
927 }
928 }
929
930 void CertificateManagerHandler::Populate(const ListValue* args) {
931 certificate_manager_model_->Refresh();
932 }
933
934 void CertificateManagerHandler::PopulateTree(const std::string& tab_name,
935 net::CertType type) {
936 const std::string tree_name = tab_name + "-tree";
937
938 scoped_ptr<icu::Collator> collator;
939 UErrorCode error = U_ZERO_ERROR;
940 collator.reset(
941 icu::Collator::createInstance(
942 icu::Locale(g_browser_process->GetApplicationLocale().c_str()),
943 error));
944 if (U_FAILURE(error))
945 collator.reset(NULL);
946 DictionaryIdComparator comparator(collator.get());
947 CertificateManagerModel::OrgGroupingMap map;
948
949 certificate_manager_model_->FilterAndBuildOrgGroupingMap(type, &map);
950
951 {
952 ListValue* nodes = new ListValue;
953 for (CertificateManagerModel::OrgGroupingMap::iterator i = map.begin();
954 i != map.end(); ++i) {
955 // Populate first level (org name).
956 DictionaryValue* dict = new DictionaryValue;
957 dict->SetString(kKeyId, OrgNameToId(i->first));
958 dict->SetString(kNameId, i->first);
959
960 // Populate second level (certs).
961 ListValue* subnodes = new ListValue;
962 for (net::CertificateList::const_iterator org_cert_it = i->second.begin();
963 org_cert_it != i->second.end(); ++org_cert_it) {
964 DictionaryValue* cert_dict = new DictionaryValue;
965 net::X509Certificate* cert = org_cert_it->get();
966 cert_dict->SetString(kKeyId, CertToId(*cert));
967 cert_dict->SetString(kNameId, certificate_manager_model_->GetColumnText(
968 *cert, CertificateManagerModel::COL_SUBJECT_NAME));
969 cert_dict->SetBoolean(
970 kReadOnlyId,
971 certificate_manager_model_->cert_db().IsReadOnly(cert));
972 cert_dict->SetBoolean(
973 kUntrustedId,
974 certificate_manager_model_->cert_db().IsUntrusted(cert));
975 // TODO(mattm): Other columns.
976 subnodes->Append(cert_dict);
977 }
978 std::sort(subnodes->begin(), subnodes->end(), comparator);
979
980 dict->Set(kSubNodesId, subnodes);
981 nodes->Append(dict);
982 }
983 std::sort(nodes->begin(), nodes->end(), comparator);
984
985 ListValue args;
986 args.Append(Value::CreateStringValue(tree_name));
987 args.Append(nodes);
988 web_ui()->CallJavascriptFunction("CertificateManager.onPopulateTree", args);
989 }
990 }
991
992 void CertificateManagerHandler::ShowError(const std::string& title,
993 const std::string& error) const {
994 ScopedVector<const Value> args;
995 args.push_back(Value::CreateStringValue(title));
996 args.push_back(Value::CreateStringValue(error));
997 args.push_back(Value::CreateStringValue(l10n_util::GetStringUTF8(IDS_OK)));
998 args.push_back(Value::CreateNullValue()); // cancelTitle
999 args.push_back(Value::CreateNullValue()); // okCallback
1000 args.push_back(Value::CreateNullValue()); // cancelCallback
1001 web_ui()->CallJavascriptFunction("AlertOverlay.show", args.get());
1002 }
1003
1004 void CertificateManagerHandler::ShowImportErrors(
1005 const std::string& title,
1006 const net::CertDatabase::ImportCertFailureList& not_imported) const {
1007 std::string error;
1008 if (selected_cert_list_.size() == 1)
1009 error = l10n_util::GetStringUTF8(
1010 IDS_CERT_MANAGER_IMPORT_SINGLE_NOT_IMPORTED);
1011 else if (not_imported.size() == selected_cert_list_.size())
1012 error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ALL_NOT_IMPORTED);
1013 else
1014 error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_SOME_NOT_IMPORTED);
1015
1016 ListValue cert_error_list;
1017 for (size_t i = 0; i < not_imported.size(); ++i) {
1018 const net::CertDatabase::ImportCertFailure& failure = not_imported[i];
1019 DictionaryValue* dict = new DictionaryValue;
1020 dict->SetString(kNameId, failure.certificate->subject().GetDisplayName());
1021 dict->SetString(kErrorId, NetErrorToString(failure.net_error));
1022 cert_error_list.Append(dict);
1023 }
1024
1025 StringValue title_value(title);
1026 StringValue error_value(error);
1027 web_ui()->CallJavascriptFunction("CertificateImportErrorOverlay.show",
1028 title_value,
1029 error_value,
1030 cert_error_list);
1031 }
1032
1033 #if defined(OS_CHROMEOS)
1034 void CertificateManagerHandler::CheckTpmTokenReady(const ListValue* args) {
1035 chromeos::CryptohomeClient* cryptohome_client =
1036 chromeos::DBusThreadManager::Get()->GetCryptohomeClient();
1037 cryptohome_client->Pkcs11IsTpmTokenReady(
1038 base::Bind(&CertificateManagerHandler::CheckTpmTokenReadyInternal,
1039 weak_ptr_factory_.GetWeakPtr()));
1040 }
1041
1042 void CertificateManagerHandler::CheckTpmTokenReadyInternal(
1043 chromeos::CryptohomeClient::CallStatus call_status,
1044 bool is_tpm_token_ready) {
1045 base::FundamentalValue ready(
1046 call_status == chromeos::CryptohomeClient::SUCCESS && is_tpm_token_ready);
1047 web_ui()->CallJavascriptFunction("CertificateManager.onCheckTpmTokenReady",
1048 ready);
1049 }
1050 #endif
1051
1052 gfx::NativeWindow CertificateManagerHandler::GetParentWindow() const {
1053 return web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow();
1054 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698