diff options
6 files changed, 99 insertions, 1 deletions
diff --git a/chrome/browser/certificate_manager_model.cc b/chrome/browser/certificate_manager_model.cc index 21f8665..eafb709 100644 --- a/chrome/browser/certificate_manager_model.cc +++ b/chrome/browser/certificate_manager_model.cc @@ -98,6 +98,15 @@ bool CertificateManagerModel::ImportCACerts( return result; } +bool CertificateManagerModel::ImportServerCert( + const net::CertificateList& certificates, + net::CertDatabase::ImportCertFailureList* not_imported) { + bool result = cert_db_.ImportServerCert(certificates, not_imported); + if (result && not_imported->size() != certificates.size()) + Refresh(); + return result; +} + bool CertificateManagerModel::SetCertTrust(const net::X509Certificate* cert, net::CertType type, unsigned int trust_bits) { diff --git a/chrome/browser/certificate_manager_model.h b/chrome/browser/certificate_manager_model.h index 12c16bb..4ff0be7 100644 --- a/chrome/browser/certificate_manager_model.h +++ b/chrome/browser/certificate_manager_model.h @@ -73,6 +73,18 @@ class CertificateManagerModel { unsigned int trust_bits, net::CertDatabase::ImportCertFailureList* not_imported); + // Import server certificate. The first cert should be the server cert. Any + // additional certs should be intermediate/CA certs and will be imported but + // not given any trust. + // Any certificates that could not be imported will be listed in + // |not_imported|. + // Returns false if there is an internal error, otherwise true is returned and + // |not_imported| should be checked for any certificates that were not + // imported. + bool ImportServerCert( + const net::CertificateList& certificates, + net::CertDatabase::ImportCertFailureList* not_imported); + // Set trust values for certificate. // |trust_bits| should be a bit field of TRUST_* values from CertDatabase, or // UNTRUSTED. diff --git a/chrome/browser/dom_ui/options/certificate_manager_handler.cc b/chrome/browser/dom_ui/options/certificate_manager_handler.cc index ed1e9bc..bf30674 100644 --- a/chrome/browser/dom_ui/options/certificate_manager_handler.cc +++ b/chrome/browser/dom_ui/options/certificate_manager_handler.cc @@ -34,6 +34,7 @@ static const char kErrorId[] = "error"; enum { EXPORT_PERSONAL_FILE_SELECTED = 1, IMPORT_PERSONAL_FILE_SELECTED, + IMPORT_SERVER_FILE_SELECTED, IMPORT_CA_FILE_SELECTED, }; @@ -386,6 +387,9 @@ void CertificateManagerHandler::RegisterMessages() { dom_ui_->RegisterMessageCallback("importCaCertificateTrustSelected", NewCallback(this, &CertificateManagerHandler::ImportCATrustSelected)); + dom_ui_->RegisterMessageCallback("importServerCertificate", + NewCallback(this, &CertificateManagerHandler::ImportServer)); + dom_ui_->RegisterMessageCallback("exportCertificate", NewCallback(this, &CertificateManagerHandler::Export)); @@ -414,6 +418,9 @@ void CertificateManagerHandler::FileSelected(const FilePath& path, int index, case IMPORT_PERSONAL_FILE_SELECTED: ImportPersonalFileSelected(path); break; + case IMPORT_SERVER_FILE_SELECTED: + ImportServerFileSelected(path); + break; case IMPORT_CA_FILE_SELECTED: ImportCAFileSelected(path); break; @@ -426,6 +433,7 @@ void CertificateManagerHandler::FileSelectionCanceled(void* params) { switch (reinterpret_cast<intptr_t>(params)) { case EXPORT_PERSONAL_FILE_SELECTED: case IMPORT_PERSONAL_FILE_SELECTED: + case IMPORT_SERVER_FILE_SELECTED: case IMPORT_CA_FILE_SELECTED: ImportExportCleanup(); break; @@ -643,6 +651,61 @@ void CertificateManagerHandler::ImportExportCleanup() { select_file_dialog_ = NULL; } +void CertificateManagerHandler::ImportServer(const ListValue* args) { + select_file_dialog_ = SelectFileDialog::Create(this); + ShowCertSelectFileDialog( + select_file_dialog_.get(), + SelectFileDialog::SELECT_OPEN_FILE, + FilePath(), + GetParentWindow(), + reinterpret_cast<void*>(IMPORT_SERVER_FILE_SELECTED)); +} + +void CertificateManagerHandler::ImportServerFileSelected(const FilePath& path) { + file_path_ = path; + file_access_provider_->StartRead( + file_path_, + &consumer_, + NewCallback(this, &CertificateManagerHandler::ImportServerFileRead)); +} + +void CertificateManagerHandler::ImportServerFileRead(int read_errno, + std::string data) { + if (read_errno) { + ImportExportCleanup(); + ShowError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), + l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, + UTF8ToUTF16(safe_strerror(read_errno)))); + return; + } + + selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes( + data.data(), data.size(), net::X509Certificate::FORMAT_AUTO); + if (selected_cert_list_.empty()) { + ImportExportCleanup(); + ShowError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR)); + return; + } + + net::CertDatabase::ImportCertFailureList not_imported; + bool result = certificate_manager_model_->ImportServerCert( + selected_cert_list_, + ¬_imported); + if (!result) { + ShowError( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); + } else if (!not_imported.empty()) { + ShowImportErrors( + l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), + not_imported); + } + ImportExportCleanup(); +} + void CertificateManagerHandler::ImportCA(const ListValue* args) { select_file_dialog_ = SelectFileDialog::Create(this); ShowCertSelectFileDialog(select_file_dialog_.get(), diff --git a/chrome/browser/dom_ui/options/certificate_manager_handler.h b/chrome/browser/dom_ui/options/certificate_manager_handler.h index 2182c2b..3ac3898 100644 --- a/chrome/browser/dom_ui/options/certificate_manager_handler.h +++ b/chrome/browser/dom_ui/options/certificate_manager_handler.h @@ -85,6 +85,16 @@ class CertificateManagerHandler : public OptionsPageUIHandler, void ImportPersonalPasswordSelected(const ListValue* args); void ImportPersonalFileRead(int read_errno, std::string data); + // Import Server certificates from file. Sequence goes like: + // 1. user clicks on import button -> ImportServer -> launches file selector + // 2. user selects file -> ImportServerFileSelected -> starts async read + // 3. read completes -> ImportServerFileRead -> parse certs -> attempt import + // 4a. if import succeeds -> ImportExportCleanup + // 4b. if import fails -> show error, ImportExportCleanup + void ImportServer(const ListValue* args); + void ImportServerFileSelected(const FilePath& path); + void ImportServerFileRead(int read_errno, std::string data); + // Import Certificate Authorities from file. Sequence goes like: // 1. user clicks on import button -> ImportCA -> launches file selector // 2. user selects file -> ImportCAFileSelected -> starts async read diff --git a/chrome/browser/resources/options/certificate_manager.html b/chrome/browser/resources/options/certificate_manager.html index 2a5623d..496d6d2 100644 --- a/chrome/browser/resources/options/certificate_manager.html +++ b/chrome/browser/resources/options/certificate_manager.html @@ -88,9 +88,9 @@ <!-- TODO(mattm): <button id="serverCertsTab-edit" i18n-content="edit_certificate" disabled></button> + --> <button id="serverCertsTab-import" i18n-content="import_certificate" ></button> - --> <button id="serverCertsTab-export" i18n-content="export_certificate" disabled></button> <button id="serverCertsTab-delete" i18n-content="delete_certificate" diff --git a/chrome/browser/resources/options/certificate_manager.js b/chrome/browser/resources/options/certificate_manager.js index 062fb56..5295bde 100644 --- a/chrome/browser/resources/options/certificate_manager.js +++ b/chrome/browser/resources/options/certificate_manager.js @@ -66,6 +66,10 @@ cr.define('options', function() { this.importButton.onclick = function(e) { chrome.send('importPersonalCertificate', []); } + } else if (id == 'serverCertsTab') { + this.importButton.onclick = function(e) { + chrome.send('importServerCertificate', []); + } } else if (id == 'caCertsTab') { this.importButton.onclick = function(e) { chrome.send('importCaCertificate', []); |