15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/certificate_dialogs.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/chrome_select_file_policy.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/net/x509_certificate_model.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/filename_util.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/shell_dialogs/select_file_dialog.h" 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "url/gurl.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WriterCallback(const base::FilePath& path, const std::string& data) { 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int bytes_written = base::WriteFile(path, data.data(), data.size()); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_written != static_cast<ssize_t>(data.size())) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Writing " << path.value() << " (" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << data.size() << "B) returned " << bytes_written; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WriteFileOnFileThread(const base::FilePath& path, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& data) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::FILE, FROM_HERE, base::Bind(&WriterCallback, path, data)); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string WrapAt64(const std::string &str) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string result; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < str.size(); i += 64) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append(str, i, 64); // Append clamps the len arg internally. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append("\r\n"); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetBase64String(net::X509Certificate::OSCertHandle cert) { 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string der_cert; 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!net::X509Certificate::GetDEREncoded(cert, &der_cert)) 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return std::string(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string base64; 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Base64Encode(der_cert, &base64); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "-----BEGIN CERTIFICATE-----\r\n" + 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WrapAt64(base64) + 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "-----END CERTIFICATE-----\r\n"; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// General utility functions. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Exporter : public ui::SelectFileDialog::Listener { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Exporter(WebContents* web_contents, 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::NativeWindow parent, 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::X509Certificate::OSCertHandles::iterator certs_begin, 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::X509Certificate::OSCertHandles::iterator certs_end); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~Exporter(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SelectFileDialog::Listener implemenation. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void FileSelected(const base::FilePath& path, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index, void* params) OVERRIDE; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void FileSelectionCanceled(void* params) OVERRIDE; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ui::SelectFileDialog> select_file_dialog_; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The certificate hierarchy (leaf cert first). 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::X509Certificate::OSCertHandles cert_chain_list_; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Exporter::Exporter(WebContents* web_contents, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeWindow parent, 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::X509Certificate::OSCertHandles::iterator certs_begin, 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::X509Certificate::OSCertHandles::iterator certs_end) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : select_file_dialog_(ui::SelectFileDialog::Create( 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) this, 916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) new ChromeSelectFilePolicy(web_contents))) { 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(certs_begin != certs_end); 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) for (net::X509Certificate::OSCertHandles::iterator i = certs_begin; 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) i != certs_end; 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ++i) { 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cert_chain_list_.push_back(net::X509Certificate::DupOSCertHandle(*i)); 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mattm): should this default to some directory? 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maybe SavePackage::GetSaveDirPreference? (Except that it's private.) 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::string cert_title = x509_certificate_model::GetTitle(*certs_begin); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath suggested_path = 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::GenerateFileName(GURL::EmptyGURL(), // url 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string(), // content_disposition 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string(), // referrer_charset 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cert_title, // suggested_name 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string(), // mime_type 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "certificate"); // default_name 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowCertSelectFileDialog(select_file_dialog_.get(), 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SelectFileDialog::SELECT_SAVEAS_FILE, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) suggested_path, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Exporter::~Exporter() { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There may be pending file dialogs, we need to tell them that we've gone 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // away so they don't try and call back to us. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (select_file_dialog_.get()) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_dialog_->ListenerDestroyed(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::for_each(cert_chain_list_.begin(), 1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cert_chain_list_.end(), 1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &net::X509Certificate::FreeOSCertHandle); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Exporter::FileSelected(const base::FilePath& path, int index, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* params) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string data; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (index) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < cert_chain_list_.size(); ++i) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data += GetBase64String(cert_chain_list_[i]); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch net::X509Certificate::GetDEREncoded(cert_chain_list_[0], &data); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = x509_certificate_model::GetCMSString(cert_chain_list_, 0, 1); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 5: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = x509_certificate_model::GetCMSString( 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_chain_list_, 0, cert_chain_list_.size()); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = GetBase64String(cert_chain_list_[0]); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data.empty()) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteFileOnFileThread(path, data); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Exporter::FileSelectionCanceled(void* params) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowCertSelectFileDialog(ui::SelectFileDialog* select_file_dialog, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SelectFileDialog::Type type, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& suggested_path, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeWindow parent, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* params) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SelectFileDialog::FileTypeInfo file_type_info; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions.resize(5); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pem")); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("crt")); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extension_description_overrides.push_back( 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64)); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("pem")); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("crt")); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extension_description_overrides.push_back( 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64_CHAIN)); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions[2].push_back(FILE_PATH_LITERAL("der")); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extension_description_overrides.push_back( 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_DER)); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions[3].push_back(FILE_PATH_LITERAL("p7c")); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extension_description_overrides.push_back( 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7)); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions[4].push_back(FILE_PATH_LITERAL("p7c")); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extension_description_overrides.push_back( 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7_CHAIN)); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.include_all_files = true; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_dialog->SelectFile( 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) type, base::string16(), 1913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch suggested_path, &file_type_info, 1923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1, // 1-based index for |file_type_info.extensions| to specify default. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_PATH_LITERAL("crt"), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent, params); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowCertExportDialog(WebContents* web_contents, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeWindow parent, 1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr<net::X509Certificate>& cert) { 2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::X509Certificate::OSCertHandles cert_chain; 2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cert_chain.push_back(cert->os_cert_handle()); 2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const net::X509Certificate::OSCertHandles& certs = 2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cert->GetIntermediateCertificates(); 2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cert_chain.insert(cert_chain.end(), certs.begin(), certs.end()); 2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) new Exporter(web_contents, parent, cert_chain.begin(), cert_chain.end()); 2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ShowCertExportDialog( 2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) content::WebContents* web_contents, 2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::NativeWindow parent, 2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::X509Certificate::OSCertHandles::iterator certs_begin, 2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::X509Certificate::OSCertHandles::iterator certs_end) { 2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) new Exporter(web_contents, parent, certs_begin, certs_end); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 215