Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / certificate_dialogs.cc
blobcb32713de0bf104f4552cad750c59b2c32c37429
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.
5 #include "chrome/browser/ui/certificate_dialogs.h"
8 #include <vector>
10 #include "base/base64.h"
11 #include "base/bind.h"
12 #include "base/file_util.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "chrome/browser/ui/chrome_select_file_policy.h"
16 #include "chrome/common/net/x509_certificate_model.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "grit/generated_resources.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/shell_dialogs/select_file_dialog.h"
22 using content::BrowserThread;
23 using content::WebContents;
25 namespace {
27 void WriterCallback(const base::FilePath& path, const std::string& data) {
28 int bytes_written = file_util::WriteFile(path, data.data(), data.size());
29 if (bytes_written != static_cast<ssize_t>(data.size())) {
30 LOG(ERROR) << "Writing " << path.value() << " ("
31 << data.size() << "B) returned " << bytes_written;
35 void WriteFileOnFileThread(const base::FilePath& path,
36 const std::string& data) {
37 BrowserThread::PostTask(
38 BrowserThread::FILE, FROM_HERE, base::Bind(&WriterCallback, path, data));
41 std::string WrapAt64(const std::string &str) {
42 std::string result;
43 for (size_t i = 0; i < str.size(); i += 64) {
44 result.append(str, i, 64); // Append clamps the len arg internally.
45 result.append("\r\n");
47 return result;
50 std::string GetBase64String(net::X509Certificate::OSCertHandle cert) {
51 std::string base64;
52 base::Base64Encode(x509_certificate_model::GetDerString(cert), &base64);
53 return "-----BEGIN CERTIFICATE-----\r\n" +
54 WrapAt64(base64) +
55 "-----END CERTIFICATE-----\r\n";
58 ////////////////////////////////////////////////////////////////////////////////
59 // General utility functions.
61 class Exporter : public ui::SelectFileDialog::Listener {
62 public:
63 Exporter(WebContents* web_contents, gfx::NativeWindow parent,
64 net::X509Certificate::OSCertHandle cert);
65 virtual ~Exporter();
67 // SelectFileDialog::Listener implemenation.
68 virtual void FileSelected(const base::FilePath& path,
69 int index, void* params) OVERRIDE;
70 virtual void FileSelectionCanceled(void* params) OVERRIDE;
71 private:
72 scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
74 // The certificate hierarchy (leaf cert first).
75 net::X509Certificate::OSCertHandles cert_chain_list_;
78 Exporter::Exporter(WebContents* web_contents,
79 gfx::NativeWindow parent,
80 net::X509Certificate::OSCertHandle cert)
81 : select_file_dialog_(ui::SelectFileDialog::Create(
82 this, new ChromeSelectFilePolicy(web_contents))) {
83 x509_certificate_model::GetCertChainFromCert(cert, &cert_chain_list_);
85 // TODO(mattm): should this default to some directory?
86 // Maybe SavePackage::GetSaveDirPreference? (Except that it's private.)
87 base::FilePath suggested_path("certificate");
88 std::string cert_title = x509_certificate_model::GetTitle(cert);
89 if (!cert_title.empty())
90 suggested_path = base::FilePath(cert_title);
92 ShowCertSelectFileDialog(select_file_dialog_.get(),
93 ui::SelectFileDialog::SELECT_SAVEAS_FILE,
94 suggested_path,
95 parent,
96 NULL);
99 Exporter::~Exporter() {
100 // There may be pending file dialogs, we need to tell them that we've gone
101 // away so they don't try and call back to us.
102 if (select_file_dialog_.get())
103 select_file_dialog_->ListenerDestroyed();
105 x509_certificate_model::DestroyCertChain(&cert_chain_list_);
108 void Exporter::FileSelected(const base::FilePath& path, int index,
109 void* params) {
110 std::string data;
111 switch (index) {
112 case 2:
113 for (size_t i = 0; i < cert_chain_list_.size(); ++i)
114 data += GetBase64String(cert_chain_list_[i]);
115 break;
116 case 3:
117 data = x509_certificate_model::GetDerString(cert_chain_list_[0]);
118 break;
119 case 4:
120 data = x509_certificate_model::GetCMSString(cert_chain_list_, 0, 1);
121 break;
122 case 5:
123 data = x509_certificate_model::GetCMSString(
124 cert_chain_list_, 0, cert_chain_list_.size());
125 break;
126 case 1:
127 default:
128 data = GetBase64String(cert_chain_list_[0]);
129 break;
132 if (!data.empty())
133 WriteFileOnFileThread(path, data);
135 delete this;
138 void Exporter::FileSelectionCanceled(void* params) {
139 delete this;
142 } // namespace
144 void ShowCertSelectFileDialog(ui::SelectFileDialog* select_file_dialog,
145 ui::SelectFileDialog::Type type,
146 const base::FilePath& suggested_path,
147 gfx::NativeWindow parent,
148 void* params) {
149 ui::SelectFileDialog::FileTypeInfo file_type_info;
150 file_type_info.extensions.resize(5);
151 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pem"));
152 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("crt"));
153 file_type_info.extension_description_overrides.push_back(
154 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64));
155 file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("pem"));
156 file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("crt"));
157 file_type_info.extension_description_overrides.push_back(
158 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64_CHAIN));
159 file_type_info.extensions[2].push_back(FILE_PATH_LITERAL("der"));
160 file_type_info.extension_description_overrides.push_back(
161 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_DER));
162 file_type_info.extensions[3].push_back(FILE_PATH_LITERAL("p7c"));
163 file_type_info.extension_description_overrides.push_back(
164 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7));
165 file_type_info.extensions[4].push_back(FILE_PATH_LITERAL("p7c"));
166 file_type_info.extension_description_overrides.push_back(
167 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7_CHAIN));
168 file_type_info.include_all_files = true;
169 select_file_dialog->SelectFile(
170 type, base::string16(),
171 suggested_path, &file_type_info,
172 1, // 1-based index for |file_type_info.extensions| to specify default.
173 FILE_PATH_LITERAL("crt"),
174 parent, params);
177 void ShowCertExportDialog(WebContents* web_contents,
178 gfx::NativeWindow parent,
179 net::X509Certificate::OSCertHandle cert) {
180 new Exporter(web_contents, parent, cert);