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

Side by Side Diff: chrome/browser/gtk/certificate_dialogs.cc

Issue 3565006: Decouples certificates viewers from NSS to prepare support for OpenSSL. (Closed)
Patch Set: Comments / ProcessIDN Created 10 years, 2 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
« no previous file with comments | « chrome/browser/gtk/certificate_dialogs.h ('k') | chrome/browser/gtk/certificate_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // TODO(mattm): this isn't gtk specific, it shouldn't be under the gtk dir 5 // TODO(mattm): this isn't gtk specific, it shouldn't be under the gtk dir
6 6
7 // TODO(mattm): the nss export functions should be moved to cert_database_nss or
8 // x509_certificate_nss.
9
10 #include "chrome/browser/gtk/certificate_dialogs.h" 7 #include "chrome/browser/gtk/certificate_dialogs.h"
11 8
12 #include <cms.h>
13 9
14 #include <vector> 10 #include <vector>
15 11
16 #include "app/l10n_util.h" 12 #include "app/l10n_util.h"
17 #include "base/base64.h" 13 #include "base/base64.h"
18 #include "base/file_util.h" 14 #include "base/file_util.h"
19 #include "base/logging.h" 15 #include "base/logging.h"
20 #include "base/scoped_ptr.h" 16 #include "base/scoped_ptr.h"
21 #include "base/task.h" 17 #include "base/task.h"
22 #include "chrome/browser/chrome_thread.h" 18 #include "chrome/browser/chrome_thread.h"
23 #include "chrome/browser/shell_dialogs.h" 19 #include "chrome/browser/shell_dialogs.h"
24 #include "chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h" 20 #include "chrome/common/net/x509_certificate_model.h"
25 #include "chrome/third_party/mozilla_security_manager/nsNSSCertificate.h"
26 #include "grit/generated_resources.h" 21 #include "grit/generated_resources.h"
27 22
28 // PSM = Mozilla's Personal Security Manager.
29 namespace psm = mozilla_security_manager;
30
31 namespace { 23 namespace {
32 24
33 //////////////////////////////////////////////////////////////////////////////// 25 ////////////////////////////////////////////////////////////////////////////////
34 // General utility functions. 26 // General utility functions.
35 27
36 class Writer : public Task { 28 class Writer : public Task {
37 public: 29 public:
38 Writer(const FilePath& path, const std::string& data) 30 Writer(const FilePath& path, const std::string& data)
39 : path_(path), data_(data) { 31 : path_(path), data_(data) {
40 } 32 }
41 33
42 virtual void Run() { 34 virtual void Run() {
43 int bytes_written = file_util::WriteFile(path_, data_.data(), data_.size()); 35 int bytes_written = file_util::WriteFile(path_, data_.data(), data_.size());
44 if (bytes_written != static_cast<ssize_t>(data_.size())) { 36 if (bytes_written != static_cast<ssize_t>(data_.size())) {
45 LOG(ERROR) << "Writing " << path_.value() << " (" 37 LOG(ERROR) << "Writing " << path_.value() << " ("
46 << data_.size() << "B) returned " << bytes_written; 38 << data_.size() << "B) returned " << bytes_written;
47 } 39 }
48 } 40 }
49 private: 41 private:
50 FilePath path_; 42 FilePath path_;
51 std::string data_; 43 std::string data_;
52 }; 44 };
53 45
54 void WriteFileOnFileThread(const FilePath& path, const std::string& data) { 46 void WriteFileOnFileThread(const FilePath& path, const std::string& data) {
55 ChromeThread::PostTask( 47 ChromeThread::PostTask(
56 ChromeThread::FILE, FROM_HERE, new Writer(path, data)); 48 ChromeThread::FILE, FROM_HERE, new Writer(path, data));
57 } 49 }
58 50
59 ////////////////////////////////////////////////////////////////////////////////
60 // NSS certificate export functions.
61
62 class FreeNSSCMSMessage {
63 public:
64 inline void operator()(NSSCMSMessage* x) const {
65 NSS_CMSMessage_Destroy(x);
66 }
67 };
68 typedef scoped_ptr_malloc<NSSCMSMessage, FreeNSSCMSMessage>
69 ScopedNSSCMSMessage;
70
71 class FreeNSSCMSSignedData {
72 public:
73 inline void operator()(NSSCMSSignedData* x) const {
74 NSS_CMSSignedData_Destroy(x);
75 }
76 };
77 typedef scoped_ptr_malloc<NSSCMSSignedData, FreeNSSCMSSignedData>
78 ScopedNSSCMSSignedData;
79
80 std::string GetDerString(CERTCertificate* cert) {
81 return std::string(reinterpret_cast<const char*>(cert->derCert.data),
82 cert->derCert.len);
83 }
84
85 std::string WrapAt64(const std::string &str) { 51 std::string WrapAt64(const std::string &str) {
86 std::string result; 52 std::string result;
87 for (size_t i = 0; i < str.size(); i += 64) { 53 for (size_t i = 0; i < str.size(); i += 64) {
88 result.append(str, i, 64); // Append clamps the len arg internally. 54 result.append(str, i, 64); // Append clamps the len arg internally.
89 result.append("\r\n"); 55 result.append("\r\n");
90 } 56 }
91 return result; 57 return result;
92 } 58 }
93 59
94 std::string GetBase64String(CERTCertificate* cert) { 60 std::string GetBase64String(net::X509Certificate::OSCertHandle cert) {
95 std::string base64; 61 std::string base64;
96 if (!base::Base64Encode(GetDerString(cert), &base64)) { 62 if (!base::Base64Encode(
63 x509_certificate_model::GetDerString(cert), &base64)) {
97 LOG(ERROR) << "base64 encoding error"; 64 LOG(ERROR) << "base64 encoding error";
98 return ""; 65 return "";
99 } 66 }
100 return "-----BEGIN CERTIFICATE-----\r\n" + 67 return "-----BEGIN CERTIFICATE-----\r\n" +
101 WrapAt64(base64) + 68 WrapAt64(base64) +
102 "-----END CERTIFICATE-----\r\n"; 69 "-----END CERTIFICATE-----\r\n";
103 } 70 }
104 71
105 std::string GetCMSString(std::vector<CERTCertificate*> cert_chain, size_t start,
106 size_t end) {
107 ScopedPRArenaPool arena(PORT_NewArena(1024));
108 CHECK(arena.get());
109
110 ScopedNSSCMSMessage message(NSS_CMSMessage_Create(arena.get()));
111 CHECK(message.get());
112
113 // First, create SignedData with the certificate only (no chain).
114 ScopedNSSCMSSignedData signed_data(
115 NSS_CMSSignedData_CreateCertsOnly(message.get(), cert_chain[start],
116 PR_FALSE));
117 if (!signed_data.get()) {
118 LOG(ERROR) << "NSS_CMSSignedData_Create failed";
119 return "";
120 }
121 // Add the rest of the chain (if any).
122 for (size_t i = start + 1; i < end; ++i) {
123 if (NSS_CMSSignedData_AddCertificate(signed_data.get(), cert_chain[i]) !=
124 SECSuccess) {
125 LOG(ERROR) << "NSS_CMSSignedData_AddCertificate failed on " << i;
126 return "";
127 }
128 }
129
130 NSSCMSContentInfo *cinfo = NSS_CMSMessage_GetContentInfo(message.get());
131 if (NSS_CMSContentInfo_SetContent_SignedData(
132 message.get(), cinfo, signed_data.get()) == SECSuccess) {
133 ignore_result(signed_data.release());
134 } else {
135 LOG(ERROR) << "NSS_CMSMessage_GetContentInfo failed";
136 return "";
137 }
138
139 SECItem cert_p7 = { siBuffer, NULL, 0 };
140 NSSCMSEncoderContext *ecx = NSS_CMSEncoder_Start(message.get(), NULL, NULL,
141 &cert_p7, arena.get(), NULL,
142 NULL, NULL, NULL, NULL,
143 NULL);
144 if (!ecx) {
145 LOG(ERROR) << "NSS_CMSEncoder_Start failed";
146 return "";
147 }
148
149 if (NSS_CMSEncoder_Finish(ecx) != SECSuccess) {
150 LOG(ERROR) << "NSS_CMSEncoder_Finish failed";
151 return "";
152 }
153
154 return std::string(reinterpret_cast<const char*>(cert_p7.data), cert_p7.len);
155 }
156
157 //////////////////////////////////////////////////////////////////////////////// 72 ////////////////////////////////////////////////////////////////////////////////
158 // General utility functions. 73 // General utility functions.
159 74
160 class Exporter : public SelectFileDialog::Listener { 75 class Exporter : public SelectFileDialog::Listener {
161 public: 76 public:
162 Exporter(gfx::NativeWindow parent, CERTCertificate* cert); 77 Exporter(gfx::NativeWindow parent, net::X509Certificate::OSCertHandle cert);
163 ~Exporter(); 78 ~Exporter();
164 79
165 // SelectFileDialog::Listener implemenation. 80 // SelectFileDialog::Listener implemenation.
166 virtual void FileSelected(const FilePath& path, 81 virtual void FileSelected(const FilePath& path,
167 int index, void* params); 82 int index, void* params);
168 virtual void FileSelectionCanceled(void* params); 83 virtual void FileSelectionCanceled(void* params);
169 private: 84 private:
170 scoped_refptr<SelectFileDialog> select_file_dialog_; 85 scoped_refptr<SelectFileDialog> select_file_dialog_;
171 86
172 // The certificate hierarchy (leaf cert first). 87 // The certificate hierarchy (leaf cert first).
173 CERTCertList* cert_chain_list_; 88 net::X509Certificate::OSCertHandles cert_chain_list_;
174 // The same contents of cert_chain_list_ in a vector for easier access.
175 std::vector<CERTCertificate*> cert_chain_;
176 }; 89 };
177 90
178 Exporter::Exporter(gfx::NativeWindow parent, CERTCertificate* cert) 91 Exporter::Exporter(gfx::NativeWindow parent,
92 net::X509Certificate::OSCertHandle cert)
179 : select_file_dialog_(SelectFileDialog::Create(this)) { 93 : select_file_dialog_(SelectFileDialog::Create(this)) {
180 cert_chain_list_ = CERT_GetCertChainFromCert(cert, PR_Now(), 94 x509_certificate_model::GetCertChainFromCert(cert, &cert_chain_list_);
181 certUsageSSLServer);
182 DCHECK(cert_chain_list_);
183 CERTCertListNode* node;
184 for (node = CERT_LIST_HEAD(cert_chain_list_);
185 !CERT_LIST_END(node, cert_chain_list_);
186 node = CERT_LIST_NEXT(node)) {
187 cert_chain_.push_back(node->cert);
188 }
189 95
190 // TODO(mattm): should this default to some directory? 96 // TODO(mattm): should this default to some directory?
191 // Maybe SavePackage::GetSaveDirPreference? (Except that it's private.) 97 // Maybe SavePackage::GetSaveDirPreference? (Except that it's private.)
192 FilePath suggested_path("certificate"); 98 FilePath suggested_path("certificate");
193 std::string cert_title = psm::GetCertTitle(cert); 99 std::string cert_title = x509_certificate_model::GetTitle(cert);
194 if (!cert_title.empty()) 100 if (!cert_title.empty())
195 suggested_path = FilePath(cert_title); 101 suggested_path = FilePath(cert_title);
196 102
197 SelectFileDialog::FileTypeInfo file_type_info; 103 SelectFileDialog::FileTypeInfo file_type_info;
198 file_type_info.extensions.resize(5); 104 file_type_info.extensions.resize(5);
199 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pem")); 105 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pem"));
200 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("crt")); 106 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("crt"));
201 file_type_info.extension_description_overrides.push_back( 107 file_type_info.extension_description_overrides.push_back(
202 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64)); 108 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64));
203 file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("pem")); 109 file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("pem"));
(...skipping 11 matching lines...) Expand all
215 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7_CHAIN)); 121 l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7_CHAIN));
216 file_type_info.include_all_files = true; 122 file_type_info.include_all_files = true;
217 select_file_dialog_->SelectFile( 123 select_file_dialog_->SelectFile(
218 SelectFileDialog::SELECT_SAVEAS_FILE, string16(), 124 SelectFileDialog::SELECT_SAVEAS_FILE, string16(),
219 suggested_path, &file_type_info, 1, 125 suggested_path, &file_type_info, 1,
220 FILE_PATH_LITERAL("crt"), parent, 126 FILE_PATH_LITERAL("crt"), parent,
221 NULL); 127 NULL);
222 } 128 }
223 129
224 Exporter::~Exporter() { 130 Exporter::~Exporter() {
225 CERT_DestroyCertList(cert_chain_list_); 131 x509_certificate_model::DestroyCertChain(&cert_chain_list_);
226 } 132 }
227 133
228 void Exporter::FileSelected(const FilePath& path, int index, void* params) { 134 void Exporter::FileSelected(const FilePath& path, int index, void* params) {
229 std::string data; 135 std::string data;
230 switch (index) { 136 switch (index) {
231 case 2: 137 case 2:
232 for (size_t i = 0; i < cert_chain_.size(); ++i) 138 for (size_t i = 0; i < cert_chain_list_.size(); ++i)
233 data += GetBase64String(cert_chain_[i]); 139 data += GetBase64String(cert_chain_list_[i]);
234 break; 140 break;
235 case 3: 141 case 3:
236 data = GetDerString(cert_chain_[0]); 142 data = x509_certificate_model::GetDerString(cert_chain_list_[0]);
237 break; 143 break;
238 case 4: 144 case 4:
239 data = GetCMSString(cert_chain_, 0, 1); 145 data = x509_certificate_model::GetCMSString(cert_chain_list_, 0, 1);
240 break; 146 break;
241 case 5: 147 case 5:
242 data = GetCMSString(cert_chain_, 0, cert_chain_.size()); 148 data = x509_certificate_model::GetCMSString(
149 cert_chain_list_, 0, cert_chain_list_.size());
243 break; 150 break;
244 case 1: 151 case 1:
245 default: 152 default:
246 data = GetBase64String(cert_chain_[0]); 153 data = GetBase64String(cert_chain_list_[0]);
247 break; 154 break;
248 } 155 }
249 156
250 if (!data.empty()) 157 if (!data.empty())
251 WriteFileOnFileThread(path, data); 158 WriteFileOnFileThread(path, data);
252 159
253 delete this; 160 delete this;
254 } 161 }
255 162
256 void Exporter::FileSelectionCanceled(void* params) { 163 void Exporter::FileSelectionCanceled(void* params) {
257 delete this; 164 delete this;
258 } 165 }
259 166
260 } // namespace 167 } // namespace
261 168
262 void ShowCertExportDialog(gfx::NativeWindow parent, CERTCertificate* cert) { 169 void ShowCertExportDialog(gfx::NativeWindow parent,
170 net::X509Certificate::OSCertHandle cert) {
263 new Exporter(parent, cert); 171 new Exporter(parent, cert);
264 } 172 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/certificate_dialogs.h ('k') | chrome/browser/gtk/certificate_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698