summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/certificate_manager_model.cc17
-rw-r--r--chrome/browser/certificate_manager_model.h24
-rw-r--r--chrome/browser/dom_ui/options/certificate_manager_handler.cc145
-rw-r--r--chrome/browser/dom_ui/options/certificate_manager_handler.h18
-rw-r--r--chrome/browser/gtk/certificate_dialogs.cc62
-rw-r--r--chrome/browser/gtk/certificate_dialogs.h6
-rw-r--r--chrome/browser/resources/options.html4
-rw-r--r--chrome/browser/resources/options/certificate_edit_ca_trust_overlay.js77
-rw-r--r--chrome/browser/resources/options/certificate_import_error_overlay.html9
-rw-r--r--chrome/browser/resources/options/certificate_import_error_overlay.js68
-rw-r--r--chrome/browser/resources/options/certificate_manager.html2
-rw-r--r--net/base/cert_database.h2
-rw-r--r--net/base/cert_database_nss.cc2
13 files changed, 363 insertions, 73 deletions
diff --git a/chrome/browser/certificate_manager_model.cc b/chrome/browser/certificate_manager_model.cc
index c53547c..21f8665 100644
--- a/chrome/browser/certificate_manager_model.cc
+++ b/chrome/browser/certificate_manager_model.cc
@@ -88,15 +88,14 @@ int CertificateManagerModel::ImportFromPKCS12(const std::string& data,
return result;
}
-int CertificateManagerModel::ExportToPKCS12(const net::CertificateList& certs,
- const string16& password,
- std::string* output) const {
- return cert_db_.ExportToPKCS12(certs, password, output);
-}
-
-unsigned int CertificateManagerModel::GetCertTrust(
- const net::X509Certificate* cert, net::CertType type) const {
- return cert_db_.GetCertTrust(cert, type);
+bool CertificateManagerModel::ImportCACerts(
+ const net::CertificateList& certificates,
+ unsigned int trust_bits,
+ net::CertDatabase::ImportCertFailureList* not_imported) {
+ bool result = cert_db_.ImportCACerts(certificates, trust_bits, not_imported);
+ if (result && not_imported->size() != certificates.size())
+ Refresh();
+ return result;
}
bool CertificateManagerModel::SetCertTrust(const net::X509Certificate* cert,
diff --git a/chrome/browser/certificate_manager_model.h b/chrome/browser/certificate_manager_model.h
index e43af4c..12c16bb 100644
--- a/chrome/browser/certificate_manager_model.h
+++ b/chrome/browser/certificate_manager_model.h
@@ -41,6 +41,9 @@ class CertificateManagerModel {
explicit CertificateManagerModel(Observer* observer);
~CertificateManagerModel();
+ // Accessor for read-only access to the underlying CertDatabase.
+ const net::CertDatabase& cert_db() const { return cert_db_; }
+
// Refresh the list of certs. Following this call, the observer
// CertificatesRefreshed method will be called so the view can call
// FilterAndBuildOrgGroupingMap as necessary to refresh its tree views.
@@ -57,17 +60,18 @@ class CertificateManagerModel {
// |password|. Returns a net error code on failure.
int ImportFromPKCS12(const std::string& data, const string16& password);
- // Export certificates as PKCS #12 encoded |output|, using the given
- // |password|. Returns number of certs exported.
- int ExportToPKCS12(const net::CertificateList& certs,
- const string16& password,
- std::string* output) const;
-
- // Get trust bits for certificate.
- // Return value will be a bit field of TRUST_* values from CertDatabase, or
+ // Import CA certificates.
+ // Tries to import all the certificates given. The root will be trusted
+ // according to |trust_bits|. Any certificates that could not be imported
+ // will be listed in |not_imported|.
+ // |trust_bits| should be a bit field of TRUST_* values from CertDatabase, or
// UNTRUSTED.
- unsigned int GetCertTrust(const net::X509Certificate* cert,
- net::CertType type) const;
+ // 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 ImportCACerts(const net::CertificateList& certificates,
+ unsigned int trust_bits,
+ net::CertDatabase::ImportCertFailureList* not_imported);
// Set trust values for certificate.
// |trust_bits| should be a bit field of TRUST_* values from CertDatabase, or
diff --git a/chrome/browser/dom_ui/options/certificate_manager_handler.cc b/chrome/browser/dom_ui/options/certificate_manager_handler.cc
index 8287054..ed1e9bc 100644
--- a/chrome/browser/dom_ui/options/certificate_manager_handler.cc
+++ b/chrome/browser/dom_ui/options/certificate_manager_handler.cc
@@ -27,11 +27,14 @@ static const char kSubNodesId[] = "subnodes";
static const char kNameId[] = "name";
static const char kIconId[] = "icon";
static const char kSecurityDeviceId[] = "device";
+static const char kErrorId[] = "error";
-// Enumeration of different callers of SelectFile.
+// Enumeration of different callers of SelectFile. (Start counting at 1 so
+// if SelectFile is accidentally called with params=NULL it won't match any.)
enum {
- EXPORT_PERSONAL_FILE_SELECTED,
+ EXPORT_PERSONAL_FILE_SELECTED = 1,
IMPORT_PERSONAL_FILE_SELECTED,
+ IMPORT_CA_FILE_SELECTED,
};
// TODO(mattm): These are duplicated from cookies_view_handler.cc
@@ -112,6 +115,16 @@ struct DictionaryIdComparator {
icu::Collator* collator_;
};
+std::string NetErrorToString(int net_error) {
+ switch (net_error) {
+ // TODO(mattm): handle more cases.
+ case net::ERR_IMPORT_CA_CERT_NOT_CA:
+ return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_ERROR_NOT_CA);
+ default:
+ return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR);
+ }
+}
+
} // namespace
///////////////////////////////////////////////////////////////////////////////
@@ -320,18 +333,23 @@ void CertificateManagerHandler::GetLocalizedValues(
localized_strings->SetString("certificateConfirmPasswordLabel",
l10n_util::GetStringUTF16(IDS_CERT_MANAGER_CONFIRM_PASSWORD_LABEL));
- // Edit CA Trust overlay strings.
+ // Edit CA Trust & Import CA overlay strings.
localized_strings->SetString("certificateEditTrustLabel",
l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_TRUST_LABEL));
localized_strings->SetString("certificateEditCaTrustDescriptionFormat",
l10n_util::GetStringUTF16(
IDS_CERT_MANAGER_EDIT_CA_TRUST_DESCRIPTION_FORMAT));
+ localized_strings->SetString("certificateImportCaDescriptionFormat",
+ l10n_util::GetStringUTF16(
+ IDS_CERT_MANAGER_IMPORT_CA_DESCRIPTION_FORMAT));
localized_strings->SetString("certificateCaTrustSSLLabel",
l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_SSL_LABEL));
localized_strings->SetString("certificateCaTrustEmailLabel",
l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_EMAIL_LABEL));
localized_strings->SetString("certificateCaTrustObjSignLabel",
l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_OBJSIGN_LABEL));
+ localized_strings->SetString("certificateImportErrorFormat",
+ l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_ERROR_FORMAT));
}
void CertificateManagerHandler::RegisterMessages() {
@@ -365,6 +383,8 @@ void CertificateManagerHandler::RegisterMessages() {
dom_ui_->RegisterMessageCallback("importCaCertificate",
NewCallback(this, &CertificateManagerHandler::ImportCA));
+ dom_ui_->RegisterMessageCallback("importCaCertificateTrustSelected",
+ NewCallback(this, &CertificateManagerHandler::ImportCATrustSelected));
dom_ui_->RegisterMessageCallback("exportCertificate",
NewCallback(this, &CertificateManagerHandler::Export));
@@ -394,6 +414,9 @@ void CertificateManagerHandler::FileSelected(const FilePath& path, int index,
case IMPORT_PERSONAL_FILE_SELECTED:
ImportPersonalFileSelected(path);
break;
+ case IMPORT_CA_FILE_SELECTED:
+ ImportCAFileSelected(path);
+ break;
default:
NOTREACHED();
}
@@ -403,6 +426,7 @@ void CertificateManagerHandler::FileSelectionCanceled(void* params) {
switch (reinterpret_cast<intptr_t>(params)) {
case EXPORT_PERSONAL_FILE_SELECTED:
case IMPORT_PERSONAL_FILE_SELECTED:
+ case IMPORT_CA_FILE_SELECTED:
ImportExportCleanup();
break;
default:
@@ -424,7 +448,8 @@ void CertificateManagerHandler::GetCATrust(const ListValue* args) {
return;
}
- int trust = certificate_manager_model_->GetCertTrust(cert, net::CA_CERT);
+ int trust = certificate_manager_model_->cert_db().GetCertTrust(
+ cert, net::CA_CERT);
FundamentalValue ssl_value(bool(trust & net::CertDatabase::TRUSTED_SSL));
FundamentalValue email_value(bool(trust & net::CertDatabase::TRUSTED_EMAIL));
FundamentalValue obj_sign_value(
@@ -508,7 +533,7 @@ void CertificateManagerHandler::ExportPersonalPasswordSelected(
return;
}
std::string output;
- int num_exported = certificate_manager_model_->ExportToPKCS12(
+ int num_exported = certificate_manager_model_->cert_db().ExportToPKCS12(
selected_cert_list_,
password_,
&output);
@@ -619,7 +644,86 @@ void CertificateManagerHandler::ImportExportCleanup() {
}
void CertificateManagerHandler::ImportCA(const ListValue* args) {
- NOTIMPLEMENTED();
+ select_file_dialog_ = SelectFileDialog::Create(this);
+ ShowCertSelectFileDialog(select_file_dialog_.get(),
+ SelectFileDialog::SELECT_OPEN_FILE,
+ FilePath(),
+ GetParentWindow(),
+ reinterpret_cast<void*>(IMPORT_CA_FILE_SELECTED));
+}
+
+void CertificateManagerHandler::ImportCAFileSelected(const FilePath& path) {
+ file_path_ = path;
+ file_access_provider_->StartRead(
+ file_path_,
+ &consumer_,
+ NewCallback(this, &CertificateManagerHandler::ImportCAFileRead));
+}
+
+void CertificateManagerHandler::ImportCAFileRead(int read_errno,
+ std::string data) {
+ if (read_errno) {
+ ImportExportCleanup();
+ ShowError(
+ l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_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_CA_IMPORT_ERROR_TITLE),
+ l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR));
+ return;
+ }
+
+ scoped_refptr<net::X509Certificate> root_cert =
+ certificate_manager_model_->cert_db().FindRootInList(selected_cert_list_);
+
+ // TODO(mattm): check here if root_cert is not a CA cert and show error.
+
+ StringValue cert_name(root_cert->subject().GetDisplayName());
+ dom_ui_->CallJavascriptFunction(L"CertificateEditCaTrustOverlay.showImport",
+ cert_name);
+}
+
+void CertificateManagerHandler::ImportCATrustSelected(const ListValue* args) {
+ bool fail = false;
+ bool trust_ssl;
+ bool trust_email;
+ bool trust_obj_sign;
+ fail |= !CallbackArgsToBool(args, 0, &trust_ssl);
+ fail |= !CallbackArgsToBool(args, 1, &trust_email);
+ fail |= !CallbackArgsToBool(args, 2, &trust_obj_sign);
+ if (fail) {
+ LOG(ERROR) << "ImportCATrustSelected args fail";
+ ImportExportCleanup();
+ dom_ui_->CallJavascriptFunction(L"CertificateEditCaTrustOverlay.dismiss");
+ return;
+ }
+
+ net::CertDatabase::ImportCertFailureList not_imported;
+ bool result = certificate_manager_model_->ImportCACerts(
+ selected_cert_list_,
+ trust_ssl * net::CertDatabase::TRUSTED_SSL +
+ trust_email * net::CertDatabase::TRUSTED_EMAIL +
+ trust_obj_sign * net::CertDatabase::TRUSTED_OBJ_SIGN,
+ &not_imported);
+ dom_ui_->CallJavascriptFunction(L"CertificateEditCaTrustOverlay.dismiss");
+ if (!result) {
+ ShowError(
+ l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
+ l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
+ } else if (!not_imported.empty()) {
+ ShowImportErrors(
+ l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
+ not_imported);
+ }
+ ImportExportCleanup();
}
void CertificateManagerHandler::Export(const ListValue* args) {
@@ -711,6 +815,35 @@ void CertificateManagerHandler::ShowError(const std::string& title,
dom_ui_->CallJavascriptFunction(L"AlertOverlay.show", args);
}
+void CertificateManagerHandler::ShowImportErrors(
+ const std::string& title,
+ const net::CertDatabase::ImportCertFailureList& not_imported) const {
+ std::string error;
+ if (selected_cert_list_.size() == 1)
+ error = l10n_util::GetStringUTF8(
+ IDS_CERT_MANAGER_IMPORT_SINGLE_NOT_IMPORTED);
+ else if (not_imported.size() == selected_cert_list_.size())
+ error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ALL_NOT_IMPORTED);
+ else
+ error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_SOME_NOT_IMPORTED);
+
+ ListValue cert_error_list;
+ for (size_t i = 0; i < not_imported.size(); ++i) {
+ const net::CertDatabase::ImportCertFailure& failure = not_imported[i];
+ DictionaryValue* dict = new DictionaryValue;
+ dict->SetString(kNameId, failure.certificate->subject().GetDisplayName());
+ dict->SetString(kErrorId, NetErrorToString(failure.net_error));
+ cert_error_list.Append(dict);
+ }
+
+ StringValue title_value(title);
+ StringValue error_value(error);
+ dom_ui_->CallJavascriptFunction(L"CertificateImportErrorOverlay.show",
+ title_value,
+ error_value,
+ cert_error_list);
+}
+
gfx::NativeWindow CertificateManagerHandler::GetParentWindow() const {
return dom_ui_->tab_contents()->view()->GetTopLevelNativeWindow();
}
diff --git a/chrome/browser/dom_ui/options/certificate_manager_handler.h b/chrome/browser/dom_ui/options/certificate_manager_handler.h
index fc335e6..2182c2b 100644
--- a/chrome/browser/dom_ui/options/certificate_manager_handler.h
+++ b/chrome/browser/dom_ui/options/certificate_manager_handler.h
@@ -85,7 +85,18 @@ class CertificateManagerHandler : public OptionsPageUIHandler,
void ImportPersonalPasswordSelected(const ListValue* args);
void ImportPersonalFileRead(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
+ // 3. read completes -> ImportCAFileRead -> parse certs ->
+ // CertificateEditCaTrustOverlay.showImport
+ // 4. user clicks ok -> ImportCATrustSelected -> attempt import
+ // 5a. if import succeeds -> ImportExportCleanup
+ // 5b. if import fails -> show error, ImportExportCleanup
void ImportCA(const ListValue* args);
+ void ImportCAFileSelected(const FilePath& path);
+ void ImportCAFileRead(int read_errno, std::string data);
+ void ImportCATrustSelected(const ListValue* args);
// Export a certificate.
void Export(const ListValue* args);
@@ -102,6 +113,13 @@ class CertificateManagerHandler : public OptionsPageUIHandler,
// Display a domui error message box.
void ShowError(const std::string& title, const std::string& error) const;
+ // Display a domui error message box for import failures.
+ // Depends on |selected_cert_list_| being set to the imports that we
+ // attempted to import.
+ void ShowImportErrors(
+ const std::string& title,
+ const net::CertDatabase::ImportCertFailureList& not_imported) const;
+
gfx::NativeWindow GetParentWindow() const;
// The Certificates Manager model
diff --git a/chrome/browser/gtk/certificate_dialogs.cc b/chrome/browser/gtk/certificate_dialogs.cc
index 920899c..8709bb4 100644
--- a/chrome/browser/gtk/certificate_dialogs.cc
+++ b/chrome/browser/gtk/certificate_dialogs.cc
@@ -100,31 +100,11 @@ Exporter::Exporter(gfx::NativeWindow parent,
if (!cert_title.empty())
suggested_path = FilePath(cert_title);
- SelectFileDialog::FileTypeInfo file_type_info;
- file_type_info.extensions.resize(5);
- file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pem"));
- file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("crt"));
- file_type_info.extension_description_overrides.push_back(
- l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64));
- file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("pem"));
- file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("crt"));
- file_type_info.extension_description_overrides.push_back(
- l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64_CHAIN));
- file_type_info.extensions[2].push_back(FILE_PATH_LITERAL("der"));
- file_type_info.extension_description_overrides.push_back(
- l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_DER));
- file_type_info.extensions[3].push_back(FILE_PATH_LITERAL("p7c"));
- file_type_info.extension_description_overrides.push_back(
- l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7));
- file_type_info.extensions[4].push_back(FILE_PATH_LITERAL("p7c"));
- file_type_info.extension_description_overrides.push_back(
- l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7_CHAIN));
- file_type_info.include_all_files = true;
- select_file_dialog_->SelectFile(
- SelectFileDialog::SELECT_SAVEAS_FILE, string16(),
- suggested_path, &file_type_info, 1,
- FILE_PATH_LITERAL("crt"), parent,
- NULL);
+ ShowCertSelectFileDialog(select_file_dialog_.get(),
+ SelectFileDialog::SELECT_SAVEAS_FILE,
+ suggested_path,
+ parent,
+ NULL);
}
Exporter::~Exporter() {
@@ -166,6 +146,38 @@ void Exporter::FileSelectionCanceled(void* params) {
} // namespace
+void ShowCertSelectFileDialog(SelectFileDialog* select_file_dialog,
+ SelectFileDialog::Type type,
+ const FilePath& suggested_path,
+ gfx::NativeWindow parent,
+ void* params) {
+ SelectFileDialog::FileTypeInfo file_type_info;
+ file_type_info.extensions.resize(5);
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pem"));
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("crt"));
+ file_type_info.extension_description_overrides.push_back(
+ l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64));
+ file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("pem"));
+ file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("crt"));
+ file_type_info.extension_description_overrides.push_back(
+ l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_BASE64_CHAIN));
+ file_type_info.extensions[2].push_back(FILE_PATH_LITERAL("der"));
+ file_type_info.extension_description_overrides.push_back(
+ l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_DER));
+ file_type_info.extensions[3].push_back(FILE_PATH_LITERAL("p7c"));
+ file_type_info.extension_description_overrides.push_back(
+ l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7));
+ file_type_info.extensions[4].push_back(FILE_PATH_LITERAL("p7c"));
+ file_type_info.extension_description_overrides.push_back(
+ l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7_CHAIN));
+ file_type_info.include_all_files = true;
+ select_file_dialog->SelectFile(
+ type, string16(),
+ suggested_path, &file_type_info, 1,
+ FILE_PATH_LITERAL("crt"), parent,
+ params);
+}
+
void ShowCertExportDialog(gfx::NativeWindow parent,
net::X509Certificate::OSCertHandle cert) {
new Exporter(parent, cert);
diff --git a/chrome/browser/gtk/certificate_dialogs.h b/chrome/browser/gtk/certificate_dialogs.h
index 403a040..e982195 100644
--- a/chrome/browser/gtk/certificate_dialogs.h
+++ b/chrome/browser/gtk/certificate_dialogs.h
@@ -9,6 +9,12 @@
#include "chrome/browser/shell_dialogs.h"
#include "net/base/x509_certificate.h"
+void ShowCertSelectFileDialog(SelectFileDialog* select_file_dialog,
+ SelectFileDialog::Type type,
+ const FilePath& suggested_path,
+ gfx::NativeWindow parent,
+ void* params);
+
void ShowCertExportDialog(gfx::NativeWindow parent,
net::X509Certificate::OSCertHandle cert);
diff --git a/chrome/browser/resources/options.html b/chrome/browser/resources/options.html
index eddc265..3006471 100644
--- a/chrome/browser/resources/options.html
+++ b/chrome/browser/resources/options.html
@@ -86,11 +86,13 @@
<script src="options/certificate_restore_overlay.js"></script>
<script src="options/certificate_backup_overlay.js"></script>
<script src="options/certificate_edit_ca_trust_overlay.js"></script>
+ <script src="options/certificate_import_error_overlay.js"></script>
<script>
var CertificateManager = options.CertificateManager;
var CertificateRestoreOverlay = options.CertificateRestoreOverlay;
var CertificateBackupOverlay = options.CertificateBackupOverlay;
var CertificateEditCaTrustOverlay = options.CertificateEditCaTrustOverlay;
+ var CertificateImportErrorOverlay = options.CertificateImportErrorOverlay;
</script>
</if>
<script src="options/add_startup_page_overlay.js"></script>
@@ -173,6 +175,7 @@ function load() {
OptionsPage.registerOverlay(CertificateRestoreOverlay.getInstance());
OptionsPage.registerOverlay(CertificateBackupOverlay.getInstance());
OptionsPage.registerOverlay(CertificateEditCaTrustOverlay.getInstance());
+ OptionsPage.registerOverlay(CertificateImportErrorOverlay.getInstance());
}
OptionsPage.registerOverlay(AddStartupPageOverlay.getInstance());
OptionsPage.registerOverlay(AlertOverlay.getInstance());
@@ -283,6 +286,7 @@ window.onpopstate = function(e) {
<include src="options/certificate_restore_overlay.html">
<include src="options/certificate_backup_overlay.html">
<include src="options/certificate_edit_ca_trust_overlay.html">
+ <include src="options/certificate_import_error_overlay.html">
</if>
</div>
<div id="main-content">
diff --git a/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.js b/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.js
index 11c7af0..bcea4e3 100644
--- a/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.js
+++ b/chrome/browser/resources/options/certificate_edit_ca_trust_overlay.js
@@ -7,7 +7,7 @@ cr.define('options', function() {
/**
* CertificateEditCaTrustOverlay class
- * Encapsulated handling of the 'enter Edit password' overlay page.
+ * Encapsulated handling of the 'edit ca trust' and 'import ca' overlay pages.
* @class
*/
function CertificateEditCaTrustOverlay() {
@@ -22,21 +22,6 @@ cr.define('options', function() {
__proto__: OptionsPage.prototype,
/**
- * Initializes the page.
- */
- initializePage: function() {
- OptionsPage.prototype.initializePage.call(this);
-
- var self = this;
- $('certificateEditCaTrustCancelButton').onclick = function(event) {
- self.cancelEdit_();
- }
- $('certificateEditCaTrustOkButton').onclick = function(event) {
- self.finishEdit_();
- }
- },
-
- /**
* Dismisses the overlay.
* @private
*/
@@ -56,7 +41,6 @@ cr.define('options', function() {
$('certificateEditCaTrustOkButton').disabled = !enabled;
},
-
/**
* Attempt the Edit operation.
* The overlay will be left up with inputs disabled until the backend
@@ -81,6 +65,31 @@ cr.define('options', function() {
cancelEdit_: function() {
this.dismissOverlay_();
},
+
+ /**
+ * Attempt the Import operation.
+ * The overlay will be left up with inputs disabled until the backend
+ * finishes and dismisses it.
+ * @private
+ */
+ finishImport_: function() {
+ // TODO(mattm): Send checked values as booleans. For now send them as
+ // strings, since DOMUIBindings::send does not support any other types :(
+ chrome.send('importCaCertificateTrustSelected',
+ [$('certificateCaTrustSSLCheckbox').checked.toString(),
+ $('certificateCaTrustEmailCheckbox').checked.toString(),
+ $('certificateCaTrustObjSignCheckbox').checked.toString()]);
+ this.enableInputs_(false);
+ },
+
+ /**
+ * Cancel the Import operation.
+ * @private
+ */
+ cancelImport_: function() {
+ chrome.send('cancelImportExportCertificate');
+ this.dismissOverlay_();
+ },
};
/**
@@ -105,15 +114,45 @@ cr.define('options', function() {
* checkbox.
*/
CertificateEditCaTrustOverlay.show = function(certId, certName) {
- CertificateEditCaTrustOverlay.getInstance().certId = certId;
+ var self = CertificateEditCaTrustOverlay.getInstance();
+ self.certId = certId;
+ $('certificateEditCaTrustCancelButton').onclick = function(event) {
+ self.cancelEdit_();
+ }
+ $('certificateEditCaTrustOkButton').onclick = function(event) {
+ self.finishEdit_();
+ }
$('certificateEditCaTrustDescription').textContent =
localStrings.getStringF('certificateEditCaTrustDescriptionFormat',
certName);
- CertificateEditCaTrustOverlay.getInstance().enableInputs_(false);
+ self.enableInputs_(false);
OptionsPage.showOverlay('certificateEditCaTrustOverlay');
chrome.send('getCaCertificateTrust', [certId]);
}
+ /**
+ * Show the Import CA overlay.
+ * @param {string} certId The id of the certificate to be passed to the
+ * certificate manager model.
+ * @param {string} certName The display name of the certificate.
+ * checkbox.
+ */
+ CertificateEditCaTrustOverlay.showImport = function(certName) {
+ var self = CertificateEditCaTrustOverlay.getInstance();
+ // TODO(mattm): do we want a view certificate button here like firefox has?
+ $('certificateEditCaTrustCancelButton').onclick = function(event) {
+ self.cancelImport_();
+ }
+ $('certificateEditCaTrustOkButton').onclick = function(event) {
+ self.finishImport_();
+ }
+ $('certificateEditCaTrustDescription').textContent =
+ localStrings.getStringF('certificateImportCaDescriptionFormat',
+ certName);
+ CertificateEditCaTrustOverlay.populateTrust(false, false, false);
+ OptionsPage.showOverlay('certificateEditCaTrustOverlay');
+ }
+
CertificateEditCaTrustOverlay.dismiss = function() {
CertificateEditCaTrustOverlay.getInstance().dismissOverlay_();
};
diff --git a/chrome/browser/resources/options/certificate_import_error_overlay.html b/chrome/browser/resources/options/certificate_import_error_overlay.html
new file mode 100644
index 0000000..5ff4b5b
--- /dev/null
+++ b/chrome/browser/resources/options/certificate_import_error_overlay.html
@@ -0,0 +1,9 @@
+<div class="page hidden" id="certificateImportErrorOverlay">
+ <h1 id="certificateImportErrorOverlayTitle"></h1>
+ <div id="certificateImportErrorOverlayMessage"></div>
+ <ul id="certificateImportErrorOverlayCertErrors"></ul>
+ <div class="button-strip">
+ <button type="submit" id="certificateImportErrorOverlayOk"
+ i18n-content="ok"></button>
+ </div>
+</div>
diff --git a/chrome/browser/resources/options/certificate_import_error_overlay.js b/chrome/browser/resources/options/certificate_import_error_overlay.js
new file mode 100644
index 0000000..222efda5
--- /dev/null
+++ b/chrome/browser/resources/options/certificate_import_error_overlay.js
@@ -0,0 +1,68 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('options', function() {
+
+ var OptionsPage = options.OptionsPage;
+
+ /**
+ * CertificateImportErrorOverlay class
+ * Displays a list of certificates and errors.
+ * @class
+ */
+ function CertificateImportErrorOverlay() {
+ OptionsPage.call(this, 'certificateImportErrorOverlay', '',
+ 'certificateImportErrorOverlay');
+ }
+
+ cr.addSingletonGetter(CertificateImportErrorOverlay);
+
+ CertificateImportErrorOverlay.prototype = {
+ // Inherit CertificateImportErrorOverlay from OptionsPage.
+ __proto__: OptionsPage.prototype,
+
+ /**
+ * Initialize the page.
+ */
+ initializePage: function() {
+ // Call base class implementation to start preference initialization.
+ OptionsPage.prototype.initializePage.call(this);
+
+ $('certificateImportErrorOverlayOk').onclick = function(event) {
+ OptionsPage.clearOverlays();
+ };
+ },
+ };
+
+ /**
+ * Show an alert overlay with the given message, button titles, and
+ * callbacks.
+ * @param {string} title The alert title to display to the user.
+ * @param {string} message The alert message to display to the user.
+ * @param {Array} certErrors The list of cert errors. Each error should have
+ * a .name and .error attribute.
+ */
+ CertificateImportErrorOverlay.show = function(title, message, certErrors) {
+ $('certificateImportErrorOverlayTitle').textContent = title;
+ $('certificateImportErrorOverlayMessage').textContent = message;
+
+ ul = $('certificateImportErrorOverlayCertErrors');
+ ul.innerHTML = '';
+ for (var i = 0; i < certErrors.length; ++i) {
+ li = document.createElement("li");
+ li.textContent = localStrings.getStringF('certificateImportErrorFormat',
+ certErrors[i].name,
+ certErrors[i].error);
+ ul.appendChild(li);
+ }
+
+ OptionsPage.showOverlay('certificateImportErrorOverlay');
+ }
+
+ // Export
+ return {
+ CertificateImportErrorOverlay: CertificateImportErrorOverlay
+ };
+
+});
diff --git a/chrome/browser/resources/options/certificate_manager.html b/chrome/browser/resources/options/certificate_manager.html
index bbccf22..2a5623d 100644
--- a/chrome/browser/resources/options/certificate_manager.html
+++ b/chrome/browser/resources/options/certificate_manager.html
@@ -112,10 +112,8 @@
disabled></button>
<button id="caCertsTab-edit" i18n-content="edit_certificate"
disabled></button>
- <!-- TODO(mattm):
<button id="caCertsTab-import" i18n-content="import_certificate"
></button>
- -->
<button id="caCertsTab-export" i18n-content="export_certificate"
disabled></button>
<button id="caCertsTab-delete" i18n-content="delete_certificate"
diff --git a/net/base/cert_database.h b/net/base/cert_database.h
index a40a56f..377c0a8 100644
--- a/net/base/cert_database.h
+++ b/net/base/cert_database.h
@@ -87,7 +87,7 @@ class CertDatabase {
// root. Assumes the list is an ordered hierarchy with the root being either
// the first or last element.
// TODO(mattm): improve this to handle any order.
- X509Certificate* FindRootInList(const CertificateList& certificates);
+ X509Certificate* FindRootInList(const CertificateList& certificates) const;
// Import CA certificates.
// Tries to import all the certificates given. The root will be trusted
diff --git a/net/base/cert_database_nss.cc b/net/base/cert_database_nss.cc
index 2c1ad92..69b2128 100644
--- a/net/base/cert_database_nss.cc
+++ b/net/base/cert_database_nss.cc
@@ -119,7 +119,7 @@ int CertDatabase::ExportToPKCS12(
}
X509Certificate* CertDatabase::FindRootInList(
- const CertificateList& certificates) {
+ const CertificateList& certificates) const {
DCHECK_GT(certificates.size(), 0U);
if (certificates.size() == 1)