| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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 // TODO(mattm): this isn't gtk specific, it shouldn't be under the gtk dir | |
| 6 | |
| 7 #include "chrome/browser/gtk/certificate_dialogs.h" | |
| 8 | |
| 9 | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "app/l10n_util.h" | |
| 13 #include "base/base64.h" | |
| 14 #include "base/file_util.h" | |
| 15 #include "base/logging.h" | |
| 16 #include "base/scoped_ptr.h" | |
| 17 #include "base/task.h" | |
| 18 #include "chrome/browser/browser_thread.h" | |
| 19 #include "chrome/browser/shell_dialogs.h" | |
| 20 #include "chrome/common/net/x509_certificate_model.h" | |
| 21 #include "grit/generated_resources.h" | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 //////////////////////////////////////////////////////////////////////////////// | |
| 26 // General utility functions. | |
| 27 | |
| 28 class Writer : public Task { | |
| 29 public: | |
| 30 Writer(const FilePath& path, const std::string& data) | |
| 31 : path_(path), data_(data) { | |
| 32 } | |
| 33 | |
| 34 virtual void Run() { | |
| 35 int bytes_written = file_util::WriteFile(path_, data_.data(), data_.size()); | |
| 36 if (bytes_written != static_cast<ssize_t>(data_.size())) { | |
| 37 LOG(ERROR) << "Writing " << path_.value() << " (" | |
| 38 << data_.size() << "B) returned " << bytes_written; | |
| 39 } | |
| 40 } | |
| 41 private: | |
| 42 FilePath path_; | |
| 43 std::string data_; | |
| 44 }; | |
| 45 | |
| 46 void WriteFileOnFileThread(const FilePath& path, const std::string& data) { | |
| 47 BrowserThread::PostTask( | |
| 48 BrowserThread::FILE, FROM_HERE, new Writer(path, data)); | |
| 49 } | |
| 50 | |
| 51 std::string WrapAt64(const std::string &str) { | |
| 52 std::string result; | |
| 53 for (size_t i = 0; i < str.size(); i += 64) { | |
| 54 result.append(str, i, 64); // Append clamps the len arg internally. | |
| 55 result.append("\r\n"); | |
| 56 } | |
| 57 return result; | |
| 58 } | |
| 59 | |
| 60 std::string GetBase64String(net::X509Certificate::OSCertHandle cert) { | |
| 61 std::string base64; | |
| 62 if (!base::Base64Encode( | |
| 63 x509_certificate_model::GetDerString(cert), &base64)) { | |
| 64 LOG(ERROR) << "base64 encoding error"; | |
| 65 return ""; | |
| 66 } | |
| 67 return "-----BEGIN CERTIFICATE-----\r\n" + | |
| 68 WrapAt64(base64) + | |
| 69 "-----END CERTIFICATE-----\r\n"; | |
| 70 } | |
| 71 | |
| 72 //////////////////////////////////////////////////////////////////////////////// | |
| 73 // General utility functions. | |
| 74 | |
| 75 class Exporter : public SelectFileDialog::Listener { | |
| 76 public: | |
| 77 Exporter(gfx::NativeWindow parent, net::X509Certificate::OSCertHandle cert); | |
| 78 ~Exporter(); | |
| 79 | |
| 80 // SelectFileDialog::Listener implemenation. | |
| 81 virtual void FileSelected(const FilePath& path, | |
| 82 int index, void* params); | |
| 83 virtual void FileSelectionCanceled(void* params); | |
| 84 private: | |
| 85 scoped_refptr<SelectFileDialog> select_file_dialog_; | |
| 86 | |
| 87 // The certificate hierarchy (leaf cert first). | |
| 88 net::X509Certificate::OSCertHandles cert_chain_list_; | |
| 89 }; | |
| 90 | |
| 91 Exporter::Exporter(gfx::NativeWindow parent, | |
| 92 net::X509Certificate::OSCertHandle cert) | |
| 93 : select_file_dialog_(SelectFileDialog::Create(this)) { | |
| 94 x509_certificate_model::GetCertChainFromCert(cert, &cert_chain_list_); | |
| 95 | |
| 96 // TODO(mattm): should this default to some directory? | |
| 97 // Maybe SavePackage::GetSaveDirPreference? (Except that it's private.) | |
| 98 FilePath suggested_path("certificate"); | |
| 99 std::string cert_title = x509_certificate_model::GetTitle(cert); | |
| 100 if (!cert_title.empty()) | |
| 101 suggested_path = FilePath(cert_title); | |
| 102 | |
| 103 ShowCertSelectFileDialog(select_file_dialog_.get(), | |
| 104 SelectFileDialog::SELECT_SAVEAS_FILE, | |
| 105 suggested_path, | |
| 106 parent, | |
| 107 NULL); | |
| 108 } | |
| 109 | |
| 110 Exporter::~Exporter() { | |
| 111 x509_certificate_model::DestroyCertChain(&cert_chain_list_); | |
| 112 } | |
| 113 | |
| 114 void Exporter::FileSelected(const FilePath& path, int index, void* params) { | |
| 115 std::string data; | |
| 116 switch (index) { | |
| 117 case 2: | |
| 118 for (size_t i = 0; i < cert_chain_list_.size(); ++i) | |
| 119 data += GetBase64String(cert_chain_list_[i]); | |
| 120 break; | |
| 121 case 3: | |
| 122 data = x509_certificate_model::GetDerString(cert_chain_list_[0]); | |
| 123 break; | |
| 124 case 4: | |
| 125 data = x509_certificate_model::GetCMSString(cert_chain_list_, 0, 1); | |
| 126 break; | |
| 127 case 5: | |
| 128 data = x509_certificate_model::GetCMSString( | |
| 129 cert_chain_list_, 0, cert_chain_list_.size()); | |
| 130 break; | |
| 131 case 1: | |
| 132 default: | |
| 133 data = GetBase64String(cert_chain_list_[0]); | |
| 134 break; | |
| 135 } | |
| 136 | |
| 137 if (!data.empty()) | |
| 138 WriteFileOnFileThread(path, data); | |
| 139 | |
| 140 delete this; | |
| 141 } | |
| 142 | |
| 143 void Exporter::FileSelectionCanceled(void* params) { | |
| 144 delete this; | |
| 145 } | |
| 146 | |
| 147 } // namespace | |
| 148 | |
| 149 void ShowCertSelectFileDialog(SelectFileDialog* select_file_dialog, | |
| 150 SelectFileDialog::Type type, | |
| 151 const FilePath& suggested_path, | |
| 152 gfx::NativeWindow parent, | |
| 153 void* params) { | |
| 154 SelectFileDialog::FileTypeInfo file_type_info; | |
| 155 file_type_info.extensions.resize(5); | |
| 156 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pem")); | |
| 157 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("crt")); | |
| 158 file_type_info.extension_description_overrides.push_back( | |
| 159 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64)); | |
| 160 file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("pem")); | |
| 161 file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("crt")); | |
| 162 file_type_info.extension_description_overrides.push_back( | |
| 163 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64_CHAIN)); | |
| 164 file_type_info.extensions[2].push_back(FILE_PATH_LITERAL("der")); | |
| 165 file_type_info.extension_description_overrides.push_back( | |
| 166 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_DER)); | |
| 167 file_type_info.extensions[3].push_back(FILE_PATH_LITERAL("p7c")); | |
| 168 file_type_info.extension_description_overrides.push_back( | |
| 169 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7)); | |
| 170 file_type_info.extensions[4].push_back(FILE_PATH_LITERAL("p7c")); | |
| 171 file_type_info.extension_description_overrides.push_back( | |
| 172 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7_CHAIN)); | |
| 173 file_type_info.include_all_files = true; | |
| 174 select_file_dialog->SelectFile( | |
| 175 type, string16(), | |
| 176 suggested_path, &file_type_info, 1, | |
| 177 FILE_PATH_LITERAL("crt"), parent, | |
| 178 params); | |
| 179 } | |
| 180 | |
| 181 void ShowCertExportDialog(gfx::NativeWindow parent, | |
| 182 net::X509Certificate::OSCertHandle cert) { | |
| 183 new Exporter(parent, cert); | |
| 184 } | |
| OLD | NEW |