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