summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-20 22:14:07 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-20 22:14:07 +0000
commit1e507001a1f4b7e9f96ad4faffd0448a586ac304 (patch)
tree3981374091abf45e8ca46a64e678efadc7c1ab38 /chrome
parentd64b07bf98e4f27da4c22da6c615b75d4b2e16bc (diff)
downloadchromium_src-1e507001a1f4b7e9f96ad4faffd0448a586ac304.zip
chromium_src-1e507001a1f4b7e9f96ad4faffd0448a586ac304.tar.gz
chromium_src-1e507001a1f4b7e9f96ad4faffd0448a586ac304.tar.bz2
Linux: Populate certificate manager with certificates.
BUG=19991 TEST=manual Review URL: http://codereview.chromium.org/1660007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45095 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/gtk/certificate_manager.cc328
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp18
-rw-r--r--chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h13
-rw-r--r--chrome/third_party/mozilla_security_manager/nsNSSCertTrust.cpp365
-rw-r--r--chrome/third_party/mozilla_security_manager/nsNSSCertTrust.h122
6 files changed, 761 insertions, 87 deletions
diff --git a/chrome/browser/gtk/certificate_manager.cc b/chrome/browser/gtk/certificate_manager.cc
index 5ce7440..9b9c03e 100644
--- a/chrome/browser/gtk/certificate_manager.cc
+++ b/chrome/browser/gtk/certificate_manager.cc
@@ -5,32 +5,48 @@
#include "chrome/browser/gtk/certificate_manager.h"
#include <cert.h>
-
#include <gtk/gtk.h>
+#include <pk11pub.h>
+
+#include <map>
+#include <string>
+#include "app/gtk_signal.h"
#include "app/l10n_util.h"
+#include "app/l10n_util_collator.h"
+#include "base/i18n/time_formatting.h"
+#include "base/nss_util.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/gtk/certificate_viewer.h"
#include "chrome/browser/gtk/gtk_util.h"
+#include "chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h"
+#include "chrome/third_party/mozilla_security_manager/nsNSSCertificate.h"
#include "grit/generated_resources.h"
+// PSM = Mozilla's Personal Security Manager.
+namespace psm = mozilla_security_manager;
+
namespace {
+// Convert a char* return value from NSS into a std::string and free the NSS
+// memory. If the arg is NULL, an empty string will be returned instead.
+std::string Stringize(char* nss_text) {
+ std::string s;
+ if (nss_text) {
+ s = nss_text;
+ PORT_Free(nss_text);
+ }
+ return s;
+}
+
////////////////////////////////////////////////////////////////////////////////
// CertificatePage class definition.
class CertificatePage {
public:
- // The categories of certificates that can be displayed.
- enum CertType {
- USER_CERTS = 0,
- EMAIL_CERTS,
- SERVER_CERTS,
- CA_CERTS,
- UNKNOWN_CERTS,
- NUM_CERT_TYPES
- };
+ explicit CertificatePage(psm::CertType type);
- explicit CertificatePage(CertType type);
+ void PopulateTree(CERTCertList* cert_list);
// Get the top-level widget of this page.
GtkWidget* widget() {
@@ -44,21 +60,33 @@ class CertificatePage {
CERT_SECURITY_DEVICE,
CERT_SERIAL_NUMBER,
CERT_EXPIRES_ON,
+ CERT_EXPIRES_ON_INT,
CERT_ADDRESS,
CERT_POINTER,
CERT_STORE_NUM_COLUMNS
};
+ gint LocaleSortFunc(GtkTreeModel* model, GtkTreeIter* a, GtkTreeIter* b,
+ int col);
+
// Gtk event callbacks.
- static void OnSelectionChanged(GtkTreeSelection* selection,
- CertificatePage* page);
- static void OnViewClicked(GtkButton *button, CertificatePage* page);
+ CHROMEG_CALLBACK_2(CertificatePage, gint, SortNameFunc, GtkTreeModel*,
+ GtkTreeIter*, GtkTreeIter*);
+ CHROMEG_CALLBACK_2(CertificatePage, gint, SortDeviceFunc, GtkTreeModel*,
+ GtkTreeIter*, GtkTreeIter*);
+ CHROMEG_CALLBACK_0(CertificatePage, void, OnSelectionChanged,
+ GtkTreeSelection*);
+ CHROMEGTK_CALLBACK_0(CertificatePage, void, OnViewClicked);
+
+ psm::CertType type_;
// The top-level widget of this page.
GtkWidget* vbox_;
+ GtkWidget* tree_;
GtkTreeStore* store_;
GtkTreeSelection* selection_;
+ scoped_ptr<icu::Collator> collator_;
GtkWidget* view_button_;
};
@@ -66,7 +94,7 @@ class CertificatePage {
////////////////////////////////////////////////////////////////////////////////
// CertificatePage implementation.
-CertificatePage::CertificatePage(CertType type) {
+CertificatePage::CertificatePage(psm::CertType type) : type_(type) {
vbox_ = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
gtk_container_set_border_width(GTK_CONTAINER(vbox_),
gtk_util::kContentAreaBorder);
@@ -79,10 +107,10 @@ CertificatePage::CertificatePage(CertType type) {
IDS_CERT_MANAGER_UNKNOWN_TREE_DESCRIPTION,
};
DCHECK_EQ(arraysize(kDescriptionIds),
- static_cast<size_t>(NUM_CERT_TYPES));
+ static_cast<size_t>(psm::NUM_CERT_TYPES));
GtkWidget* description_label = gtk_label_new(l10n_util::GetStringUTF8(
kDescriptionIds[type]).c_str());
- gtk_misc_set_alignment(GTK_MISC(description_label), 0, 0.5);
+ gtk_util::LeftAlignMisc(description_label);
gtk_box_pack_start(GTK_BOX(vbox_), description_label, FALSE, FALSE, 0);
store_ = gtk_tree_store_new(CERT_STORE_NUM_COLUMNS,
@@ -90,61 +118,87 @@ CertificatePage::CertificatePage(CertType type) {
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
+ G_TYPE_INT64,
G_TYPE_STRING,
G_TYPE_POINTER);
- GtkWidget* tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store_));
- gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), TRUE);
- selection_ = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
+ tree_ = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store_));
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_), TRUE);
+ selection_ = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_));
gtk_tree_selection_set_mode(selection_, GTK_SELECTION_SINGLE);
- g_signal_connect(selection_, "changed", G_CALLBACK(OnSelectionChanged), this);
-
- gtk_tree_view_append_column(
- GTK_TREE_VIEW(tree),
- gtk_tree_view_column_new_with_attributes(
- l10n_util::GetStringUTF8(IDS_CERT_MANAGER_NAME_COLUMN_LABEL).c_str(),
- gtk_cell_renderer_text_new(),
- "text", CERT_NAME,
- NULL));
-
- if (type == USER_CERTS || type == CA_CERTS || type == UNKNOWN_CERTS)
- gtk_tree_view_append_column(
- GTK_TREE_VIEW(tree),
- gtk_tree_view_column_new_with_attributes(
- l10n_util::GetStringUTF8(
- IDS_CERT_MANAGER_DEVICE_COLUMN_LABEL).c_str(),
- gtk_cell_renderer_text_new(),
- "text", CERT_SECURITY_DEVICE,
- NULL));
-
- if (type == USER_CERTS)
- gtk_tree_view_append_column(
- GTK_TREE_VIEW(tree),
- gtk_tree_view_column_new_with_attributes(
- l10n_util::GetStringUTF8(
- IDS_CERT_MANAGER_SERIAL_NUMBER_COLUMN_LABEL).c_str(),
- gtk_cell_renderer_text_new(),
- "text", CERT_SERIAL_NUMBER,
- NULL));
-
- if (type == USER_CERTS || type == EMAIL_CERTS || type == SERVER_CERTS)
- gtk_tree_view_append_column(
- GTK_TREE_VIEW(tree),
- gtk_tree_view_column_new_with_attributes(
- l10n_util::GetStringUTF8(
- IDS_CERT_MANAGER_EXPIRES_COLUMN_LABEL).c_str(),
- gtk_cell_renderer_text_new(),
- "text", CERT_EXPIRES_ON,
- NULL));
-
- if (type == EMAIL_CERTS)
- gtk_tree_view_append_column(
- GTK_TREE_VIEW(tree),
- gtk_tree_view_column_new_with_attributes(
- l10n_util::GetStringUTF8(
- IDS_CERT_MANAGER_EMAIL_ADDRESS_COLUMN_LABEL).c_str(),
- gtk_cell_renderer_text_new(),
- "text", CERT_ADDRESS,
- NULL));
+ g_signal_connect(selection_, "changed", G_CALLBACK(OnSelectionChangedThunk),
+ this);
+
+ GtkTreeViewColumn* name_col = gtk_tree_view_column_new_with_attributes(
+ l10n_util::GetStringUTF8(IDS_CERT_MANAGER_NAME_COLUMN_LABEL).c_str(),
+ gtk_cell_renderer_text_new(),
+ "text", CERT_NAME,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(name_col, CERT_NAME);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(tree_), name_col);
+
+ if (type == psm::USER_CERT || type == psm::CA_CERT ||
+ type == psm::UNKNOWN_CERT) {
+ GtkTreeViewColumn* device_col = gtk_tree_view_column_new_with_attributes(
+ l10n_util::GetStringUTF8(
+ IDS_CERT_MANAGER_DEVICE_COLUMN_LABEL).c_str(),
+ gtk_cell_renderer_text_new(),
+ "text", CERT_SECURITY_DEVICE,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(device_col, CERT_SECURITY_DEVICE);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(tree_), device_col);
+ }
+
+ if (type == psm::USER_CERT) {
+ GtkTreeViewColumn* serial_col = gtk_tree_view_column_new_with_attributes(
+ l10n_util::GetStringUTF8(
+ IDS_CERT_MANAGER_SERIAL_NUMBER_COLUMN_LABEL).c_str(),
+ gtk_cell_renderer_text_new(),
+ "text", CERT_SERIAL_NUMBER,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(serial_col, CERT_SERIAL_NUMBER);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(tree_), serial_col);
+ }
+
+ if (type == psm::USER_CERT || type == psm::EMAIL_CERT ||
+ type == psm::SERVER_CERT) {
+ GtkTreeViewColumn* expires_col = gtk_tree_view_column_new_with_attributes(
+ l10n_util::GetStringUTF8(
+ IDS_CERT_MANAGER_EXPIRES_COLUMN_LABEL).c_str(),
+ gtk_cell_renderer_text_new(),
+ "text", CERT_EXPIRES_ON,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(expires_col, CERT_EXPIRES_ON_INT);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(tree_), expires_col);
+ }
+
+ if (type == psm::EMAIL_CERT) {
+ GtkTreeViewColumn* addr_col = gtk_tree_view_column_new_with_attributes(
+ l10n_util::GetStringUTF8(
+ IDS_CERT_MANAGER_EMAIL_ADDRESS_COLUMN_LABEL).c_str(),
+ gtk_cell_renderer_text_new(),
+ "text", CERT_ADDRESS,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(addr_col, CERT_ADDRESS);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(tree_), addr_col);
+ }
+
+ UErrorCode error = U_ZERO_ERROR;
+ collator_.reset(
+ icu::Collator::createInstance(
+ icu::Locale(g_browser_process->GetApplicationLocale().c_str()),
+ error));
+ if (U_FAILURE(error))
+ collator_.reset(NULL);
+ if (collator_ != NULL) {
+ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store_), CERT_NAME,
+ SortNameFuncThunk, this, NULL);
+ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store_),
+ CERT_SECURITY_DEVICE, SortDeviceFuncThunk,
+ this, NULL);
+ }
+
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store_), CERT_NAME,
+ GTK_SORT_ASCENDING);
GtkWidget* scroll_window = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window),
@@ -152,7 +206,7 @@ CertificatePage::CertificatePage(CertType type) {
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(
GTK_SCROLLED_WINDOW(scroll_window), GTK_SHADOW_ETCHED_IN);
- gtk_container_add(GTK_CONTAINER(scroll_window), tree);
+ gtk_container_add(GTK_CONTAINER(scroll_window), tree_);
gtk_box_pack_start(GTK_BOX(vbox_), scroll_window, TRUE, TRUE, 0);
GtkWidget* button_box = gtk_hbox_new(FALSE, gtk_util::kControlSpacing);
@@ -164,38 +218,123 @@ CertificatePage::CertificatePage(CertType type) {
IDS_CERT_MANAGER_VIEW_CERT_BUTTON)).c_str());
gtk_widget_set_sensitive(view_button_, FALSE);
g_signal_connect(view_button_, "clicked",
- G_CALLBACK(OnViewClicked), this);
+ G_CALLBACK(OnViewClickedThunk), this);
gtk_box_pack_start(GTK_BOX(button_box), view_button_, FALSE, FALSE, 0);
// TODO(mattm): Add buttons for import, export, delete, etc
+}
+
+void CertificatePage::PopulateTree(CERTCertList* cert_list) {
+ DCHECK(gtk_tree_model_get_flags(GTK_TREE_MODEL(store_)) &
+ GTK_TREE_MODEL_ITERS_PERSIST);
+
+ typedef std::map<std::string, GtkTreeIter> OrgTreeMap;
+ OrgTreeMap org_tree_map;
+
+ CERTCertListNode* node;
+ for (node = CERT_LIST_HEAD(cert_list);
+ !CERT_LIST_END(node, cert_list);
+ node = CERT_LIST_NEXT(node)) {
+ CERTCertificate* cert = node->cert;
+ psm::CertType type = psm::GetCertType(cert);
+ if (type == type_) {
+ std::string org = Stringize(CERT_GetOrgName(&cert->subject));
+ if (org.empty())
+ org = Stringize(CERT_GetCommonName(&cert->subject));
+ OrgTreeMap::iterator org_tree_map_iter = org_tree_map.find(org);
+ if (org_tree_map_iter == org_tree_map.end()) {
+ GtkTreeIter iter;
+ gtk_tree_store_append(store_, &iter, NULL);
+ gtk_tree_store_set(store_, &iter, CERT_NAME, org.c_str(), -1);
+ org_tree_map_iter = org_tree_map.insert(std::make_pair(org,
+ iter)).first;
+ }
+ std::string name = Stringize(CERT_GetCommonName(&cert->subject));
+ if (name.empty() && cert->nickname) {
+ name = cert->nickname;
+ // Hack copied from mozilla: Cut off text before first :, which seems to
+ // just be the token name.
+ size_t colon_pos = name.find(':');
+ if (colon_pos != std::string::npos)
+ name = name.substr(colon_pos + 1);
+ }
+ GtkTreeIter iter;
+ gtk_tree_store_append(store_, &iter, &org_tree_map_iter->second);
+ gtk_tree_store_set(store_, &iter,
+ CERT_NAME, name.c_str(),
+ CERT_SECURITY_DEVICE, psm::GetCertTokenName(cert).c_str(),
+ CERT_SERIAL_NUMBER,
+ Stringize(CERT_Hexify(&cert->serialNumber, TRUE)).c_str(),
+ CERT_ADDRESS, cert->emailAddr,
+ CERT_POINTER, cert,
+ -1);
+
+ PRTime issued, expires;
+ if (CERT_GetCertTimes(cert, &issued, &expires) == SECSuccess) {
+ gtk_tree_store_set(store_, &iter,
+ CERT_EXPIRES_ON,
+ WideToUTF8(base::TimeFormatShortDateNumeric(
+ base::PRTimeToBaseTime(expires))).c_str(),
+ CERT_EXPIRES_ON_INT, expires,
+ -1);
+ }
+ }
+ }
+
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(tree_));
+}
+
+gint CertificatePage::LocaleSortFunc(GtkTreeModel* model,
+ GtkTreeIter* a,
+ GtkTreeIter* b,
+ int col) {
+ gchar* value1 = NULL;
+ gchar* value2 = NULL;
+ gtk_tree_model_get(model, a, col, &value1, -1);
+ gtk_tree_model_get(model, b, col, &value2, -1);
+ if (!value1 || !value2) {
+ if (value1)
+ return 1;
+ if (value2)
+ return -1;
+ return 0;
+ }
+
+ return l10n_util::CompareStringWithCollator(collator_.get(),
+ UTF8ToWide(value1),
+ UTF8ToWide(value2));
+}
+
+gint CertificatePage::SortNameFunc(GtkTreeModel* model, GtkTreeIter* a,
+ GtkTreeIter* b) {
+ return LocaleSortFunc(model, a, b, CERT_NAME);
+}
- // TODO(mattm): Populate the tree.
+gint CertificatePage::SortDeviceFunc(GtkTreeModel* model, GtkTreeIter* a,
+ GtkTreeIter* b) {
+ return LocaleSortFunc(model, a, b, CERT_SECURITY_DEVICE);
}
-// static
-void CertificatePage::OnSelectionChanged(GtkTreeSelection* selection,
- CertificatePage* page) {
+void CertificatePage::OnSelectionChanged(GtkTreeSelection* selection) {
CERTCertificate* cert = NULL;
GtkTreeIter iter;
GtkTreeModel* model;
- if (gtk_tree_selection_get_selected(page->selection_, &model, &iter))
+ if (gtk_tree_selection_get_selected(selection_, &model, &iter))
gtk_tree_model_get(model, &iter, CERT_POINTER, &cert, -1);
- gtk_widget_set_sensitive(page->view_button_, cert ? TRUE : FALSE);
+ gtk_widget_set_sensitive(view_button_, cert ? TRUE : FALSE);
}
-// static
-void CertificatePage::OnViewClicked(GtkButton *button, CertificatePage* page) {
+void CertificatePage::OnViewClicked(GtkWidget* button) {
GtkTreeIter iter;
GtkTreeModel* model;
- if (!gtk_tree_selection_get_selected(page->selection_, &model, &iter))
+ if (!gtk_tree_selection_get_selected(selection_, &model, &iter))
return;
CERTCertificate* cert = NULL;
gtk_tree_model_get(model, &iter, CERT_POINTER, &cert, -1);
if (cert)
- ShowCertificateViewer(GTK_WINDOW(gtk_widget_get_toplevel(page->widget())),
- cert);
+ ShowCertificateViewer(GTK_WINDOW(gtk_widget_get_toplevel(widget())), cert);
}
////////////////////////////////////////////////////////////////////////////////
@@ -204,10 +343,13 @@ void CertificatePage::OnViewClicked(GtkButton *button, CertificatePage* page) {
class CertificateManager {
public:
explicit CertificateManager(gfx::NativeWindow parent);
+ ~CertificateManager();
void Show();
private:
+ CERTCertList* cert_list_;
+
CertificatePage user_page_;
CertificatePage email_page_;
CertificatePage server_page_;
@@ -225,11 +367,11 @@ void OnDestroy(GtkDialog* dialog, CertificateManager* cert_manager) {
}
CertificateManager::CertificateManager(gfx::NativeWindow parent)
- : user_page_(CertificatePage::USER_CERTS),
- email_page_(CertificatePage::EMAIL_CERTS),
- server_page_(CertificatePage::SERVER_CERTS),
- ca_page_(CertificatePage::CA_CERTS),
- unknown_page_(CertificatePage::UNKNOWN_CERTS) {
+ : user_page_(psm::USER_CERT),
+ email_page_(psm::EMAIL_CERT),
+ server_page_(psm::SERVER_CERT),
+ ca_page_(psm::CA_CERT),
+ unknown_page_(psm::UNKNOWN_CERT) {
dialog_ = gtk_dialog_new_with_buttons(
l10n_util::GetStringUTF8(IDS_CERTIFICATE_MANAGER_TITLE).c_str(),
parent,
@@ -281,10 +423,21 @@ CertificateManager::CertificateManager(gfx::NativeWindow parent)
l10n_util::GetStringUTF8(
IDS_CERT_MANAGER_UNKNOWN_TAB_LABEL).c_str()));
+ cert_list_ = PK11_ListCerts(PK11CertListUnique, NULL);
+ user_page_.PopulateTree(cert_list_);
+ email_page_.PopulateTree(cert_list_);
+ server_page_.PopulateTree(cert_list_);
+ ca_page_.PopulateTree(cert_list_);
+ unknown_page_.PopulateTree(cert_list_);
+
g_signal_connect(dialog_, "response", G_CALLBACK(gtk_widget_destroy), NULL);
g_signal_connect(dialog_, "destroy", G_CALLBACK(OnDestroy), this);
}
+CertificateManager::~CertificateManager() {
+ CERT_DestroyCertList(cert_list_);
+}
+
void CertificateManager::Show() {
gtk_widget_show_all(dialog_);
}
@@ -292,5 +445,6 @@ void CertificateManager::Show() {
} // namespace
void ShowCertificateManager(gfx::NativeWindow parent) {
+ base::EnsureNSSInit();
(new CertificateManager(parent))->Show();
}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index ad49954..b71849a 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2534,6 +2534,8 @@
'third_party/mozilla_security_manager/nsNSSCertHelper.h',
'third_party/mozilla_security_manager/nsNSSCertificate.cpp',
'third_party/mozilla_security_manager/nsNSSCertificate.h',
+ 'third_party/mozilla_security_manager/nsNSSCertTrust.cpp',
+ 'third_party/mozilla_security_manager/nsNSSCertTrust.h',
'third_party/mozilla_security_manager/nsUsageArrayHelper.cpp',
'third_party/mozilla_security_manager/nsUsageArrayHelper.h',
],
diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
index 4058c32..8b8e279 100644
--- a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
+++ b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
@@ -46,6 +46,7 @@
#include "app/l10n_util.h"
#include "base/i18n/number_formatting.h"
#include "base/utf_string_conversions.h"
+#include "chrome/third_party/mozilla_security_manager/nsNSSCertTrust.h"
#include "grit/generated_resources.h"
#include "net/base/net_util.h"
@@ -928,4 +929,21 @@ std::string ProcessSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo* spki) {
return rv;
}
+CertType GetCertType(CERTCertificate *cert) {
+ nsNSSCertTrust trust(cert->trust);
+ if (cert->nickname && trust.HasAnyUser())
+ return USER_CERT;
+ if (trust.HasAnyCA())
+ return CA_CERT;
+ if (trust.HasPeer(PR_TRUE, PR_FALSE, PR_FALSE))
+ return SERVER_CERT;
+ if (trust.HasPeer(PR_FALSE, PR_TRUE, PR_FALSE) && cert->emailAddr)
+ return EMAIL_CERT;
+ if (CERT_IsCACert(cert, NULL))
+ return CA_CERT;
+ if (cert->emailAddr)
+ return EMAIL_CERT;
+ return UNKNOWN_CERT;
+}
+
} // namespace mozilla_security_manager
diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h
index eaa6e8b..9c98fbd 100644
--- a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h
+++ b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h
@@ -57,6 +57,17 @@ typedef scoped_ptr_malloc<PRArenaPool, FreePRArenaPool> ScopedPRArenaPool;
namespace mozilla_security_manager {
+// Constants to classify the type of a certificate. (In Mozilla this is actually
+// defined in nsIX509Cert.idl)
+enum CertType {
+ UNKNOWN_CERT,
+ CA_CERT,
+ USER_CERT,
+ EMAIL_CERT,
+ SERVER_CERT,
+ NUM_CERT_TYPES
+};
+
extern SECOidTag ms_cert_ext_certtype;
extern SECOidTag ms_certsrv_ca_version;
extern SECOidTag ms_nt_principal_name;
@@ -94,6 +105,8 @@ std::string ProcessExtKeyUsage(SECItem* extension_data);
std::string ProcessExtensionData(SECOidTag oid_tag, SECItem* extension_data);
std::string ProcessSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo* spki);
+CertType GetCertType(CERTCertificate *cert);
+
} // namespace mozilla_security_manager
#endif // CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTHELPER_H_
diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertTrust.cpp b/chrome/third_party/mozilla_security_manager/nsNSSCertTrust.cpp
new file mode 100644
index 0000000..3479366
--- /dev/null
+++ b/chrome/third_party/mozilla_security_manager/nsNSSCertTrust.cpp
@@ -0,0 +1,365 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ian McGreer <mcgreer@netscape.com>
+ * Javier Delgadillo <javi@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "chrome/third_party/mozilla_security_manager/nsNSSCertTrust.h"
+
+void
+nsNSSCertTrust::AddCATrust(PRBool ssl, PRBool email, PRBool objSign)
+{
+ if (ssl) {
+ addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CA);
+ addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA);
+ }
+ if (email) {
+ addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CA);
+ addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA);
+ }
+ if (objSign) {
+ addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CA);
+ addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA);
+ }
+}
+
+void
+nsNSSCertTrust::AddPeerTrust(PRBool ssl, PRBool email, PRBool objSign)
+{
+ if (ssl)
+ addTrust(&mTrust.sslFlags, CERTDB_TRUSTED);
+ if (email)
+ addTrust(&mTrust.emailFlags, CERTDB_TRUSTED);
+ if (objSign)
+ addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED);
+}
+
+nsNSSCertTrust::nsNSSCertTrust()
+{
+ memset(&mTrust, 0, sizeof(CERTCertTrust));
+}
+
+nsNSSCertTrust::nsNSSCertTrust(unsigned int ssl,
+ unsigned int email,
+ unsigned int objsign)
+{
+ memset(&mTrust, 0, sizeof(CERTCertTrust));
+ addTrust(&mTrust.sslFlags, ssl);
+ addTrust(&mTrust.emailFlags, email);
+ addTrust(&mTrust.objectSigningFlags, objsign);
+}
+
+nsNSSCertTrust::nsNSSCertTrust(CERTCertTrust *t)
+{
+ if (t)
+ memcpy(&mTrust, t, sizeof(CERTCertTrust));
+ else
+ memset(&mTrust, 0, sizeof(CERTCertTrust));
+}
+
+nsNSSCertTrust::~nsNSSCertTrust()
+{
+}
+
+void
+nsNSSCertTrust::SetSSLTrust(PRBool peer, PRBool tPeer,
+ PRBool ca, PRBool tCA, PRBool tClientCA,
+ PRBool user, PRBool warn)
+{
+ mTrust.sslFlags = 0;
+ if (peer || tPeer)
+ addTrust(&mTrust.sslFlags, CERTDB_VALID_PEER);
+ if (tPeer)
+ addTrust(&mTrust.sslFlags, CERTDB_TRUSTED);
+ if (ca || tCA)
+ addTrust(&mTrust.sslFlags, CERTDB_VALID_CA);
+ if (tClientCA)
+ addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA);
+ if (tCA)
+ addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CA);
+ if (user)
+ addTrust(&mTrust.sslFlags, CERTDB_USER);
+ if (warn)
+ addTrust(&mTrust.sslFlags, CERTDB_SEND_WARN);
+}
+
+void
+nsNSSCertTrust::SetEmailTrust(PRBool peer, PRBool tPeer,
+ PRBool ca, PRBool tCA, PRBool tClientCA,
+ PRBool user, PRBool warn)
+{
+ mTrust.emailFlags = 0;
+ if (peer || tPeer)
+ addTrust(&mTrust.emailFlags, CERTDB_VALID_PEER);
+ if (tPeer)
+ addTrust(&mTrust.emailFlags, CERTDB_TRUSTED);
+ if (ca || tCA)
+ addTrust(&mTrust.emailFlags, CERTDB_VALID_CA);
+ if (tClientCA)
+ addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA);
+ if (tCA)
+ addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CA);
+ if (user)
+ addTrust(&mTrust.emailFlags, CERTDB_USER);
+ if (warn)
+ addTrust(&mTrust.emailFlags, CERTDB_SEND_WARN);
+}
+
+void
+nsNSSCertTrust::SetObjSignTrust(PRBool peer, PRBool tPeer,
+ PRBool ca, PRBool tCA, PRBool tClientCA,
+ PRBool user, PRBool warn)
+{
+ mTrust.objectSigningFlags = 0;
+ if (peer || tPeer)
+ addTrust(&mTrust.objectSigningFlags, CERTDB_VALID_PEER);
+ if (tPeer)
+ addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED);
+ if (ca || tCA)
+ addTrust(&mTrust.objectSigningFlags, CERTDB_VALID_CA);
+ if (tClientCA)
+ addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA);
+ if (tCA)
+ addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CA);
+ if (user)
+ addTrust(&mTrust.objectSigningFlags, CERTDB_USER);
+ if (warn)
+ addTrust(&mTrust.objectSigningFlags, CERTDB_SEND_WARN);
+}
+
+void
+nsNSSCertTrust::SetValidCA()
+{
+ SetSSLTrust(PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetEmailTrust(PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetObjSignTrust(PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+}
+
+void
+nsNSSCertTrust::SetTrustedServerCA()
+{
+ SetSSLTrust(PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_TRUE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetEmailTrust(PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_TRUE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetObjSignTrust(PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_TRUE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+}
+
+void
+nsNSSCertTrust::SetTrustedCA()
+{
+ SetSSLTrust(PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_TRUE, PR_TRUE,
+ PR_FALSE, PR_FALSE);
+ SetEmailTrust(PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_TRUE, PR_TRUE,
+ PR_FALSE, PR_FALSE);
+ SetObjSignTrust(PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_TRUE, PR_TRUE,
+ PR_FALSE, PR_FALSE);
+}
+
+void
+nsNSSCertTrust::SetValidPeer()
+{
+ SetSSLTrust(PR_TRUE, PR_FALSE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetEmailTrust(PR_TRUE, PR_FALSE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetObjSignTrust(PR_TRUE, PR_FALSE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+}
+
+void
+nsNSSCertTrust::SetValidServerPeer()
+{
+ SetSSLTrust(PR_TRUE, PR_FALSE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetEmailTrust(PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetObjSignTrust(PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+}
+
+void
+nsNSSCertTrust::SetTrustedPeer()
+{
+ SetSSLTrust(PR_TRUE, PR_TRUE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetEmailTrust(PR_TRUE, PR_TRUE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+ SetObjSignTrust(PR_TRUE, PR_TRUE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE);
+}
+
+void
+nsNSSCertTrust::SetUser()
+{
+ SetSSLTrust(PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_FALSE);
+ SetEmailTrust(PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_FALSE);
+ SetObjSignTrust(PR_FALSE, PR_FALSE,
+ PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_FALSE);
+}
+
+PRBool
+nsNSSCertTrust::HasAnyCA()
+{
+ if (hasTrust(mTrust.sslFlags, CERTDB_VALID_CA) ||
+ hasTrust(mTrust.emailFlags, CERTDB_VALID_CA) ||
+ hasTrust(mTrust.objectSigningFlags, CERTDB_VALID_CA))
+ return PR_TRUE;
+ return PR_FALSE;
+}
+
+PRBool
+nsNSSCertTrust::HasCA(PRBool checkSSL,
+ PRBool checkEmail,
+ PRBool checkObjSign)
+{
+ if (checkSSL && !hasTrust(mTrust.sslFlags, CERTDB_VALID_CA))
+ return PR_FALSE;
+ if (checkEmail && !hasTrust(mTrust.emailFlags, CERTDB_VALID_CA))
+ return PR_FALSE;
+ if (checkObjSign && !hasTrust(mTrust.objectSigningFlags, CERTDB_VALID_CA))
+ return PR_FALSE;
+ return PR_TRUE;
+}
+
+PRBool
+nsNSSCertTrust::HasPeer(PRBool checkSSL,
+ PRBool checkEmail,
+ PRBool checkObjSign)
+{
+ if (checkSSL && !hasTrust(mTrust.sslFlags, CERTDB_VALID_PEER))
+ return PR_FALSE;
+ if (checkEmail && !hasTrust(mTrust.emailFlags, CERTDB_VALID_PEER))
+ return PR_FALSE;
+ if (checkObjSign && !hasTrust(mTrust.objectSigningFlags, CERTDB_VALID_PEER))
+ return PR_FALSE;
+ return PR_TRUE;
+}
+
+PRBool
+nsNSSCertTrust::HasAnyUser()
+{
+ if (hasTrust(mTrust.sslFlags, CERTDB_USER) ||
+ hasTrust(mTrust.emailFlags, CERTDB_USER) ||
+ hasTrust(mTrust.objectSigningFlags, CERTDB_USER))
+ return PR_TRUE;
+ return PR_FALSE;
+}
+
+PRBool
+nsNSSCertTrust::HasUser(PRBool checkSSL,
+ PRBool checkEmail,
+ PRBool checkObjSign)
+{
+ if (checkSSL && !hasTrust(mTrust.sslFlags, CERTDB_USER))
+ return PR_FALSE;
+ if (checkEmail && !hasTrust(mTrust.emailFlags, CERTDB_USER))
+ return PR_FALSE;
+ if (checkObjSign && !hasTrust(mTrust.objectSigningFlags, CERTDB_USER))
+ return PR_FALSE;
+ return PR_TRUE;
+}
+
+PRBool
+nsNSSCertTrust::HasTrustedCA(PRBool checkSSL,
+ PRBool checkEmail,
+ PRBool checkObjSign)
+{
+ if (checkSSL && !(hasTrust(mTrust.sslFlags, CERTDB_TRUSTED_CA) ||
+ hasTrust(mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA)))
+ return PR_FALSE;
+ if (checkEmail && !(hasTrust(mTrust.emailFlags, CERTDB_TRUSTED_CA) ||
+ hasTrust(mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA)))
+ return PR_FALSE;
+ if (checkObjSign &&
+ !(hasTrust(mTrust.objectSigningFlags, CERTDB_TRUSTED_CA) ||
+ hasTrust(mTrust.objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA)))
+ return PR_FALSE;
+ return PR_TRUE;
+}
+
+PRBool
+nsNSSCertTrust::HasTrustedPeer(PRBool checkSSL,
+ PRBool checkEmail,
+ PRBool checkObjSign)
+{
+ if (checkSSL && !(hasTrust(mTrust.sslFlags, CERTDB_TRUSTED)))
+ return PR_FALSE;
+ if (checkEmail && !(hasTrust(mTrust.emailFlags, CERTDB_TRUSTED)))
+ return PR_FALSE;
+ if (checkObjSign &&
+ !(hasTrust(mTrust.objectSigningFlags, CERTDB_TRUSTED)))
+ return PR_FALSE;
+ return PR_TRUE;
+}
+
+void
+nsNSSCertTrust::addTrust(unsigned int *t, unsigned int v)
+{
+ *t |= v;
+}
+
+PRBool
+nsNSSCertTrust::hasTrust(unsigned int t, unsigned int v)
+{
+ return !!(t & v);
+}
diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertTrust.h b/chrome/third_party/mozilla_security_manager/nsNSSCertTrust.h
new file mode 100644
index 0000000..832c6c5
--- /dev/null
+++ b/chrome/third_party/mozilla_security_manager/nsNSSCertTrust.h
@@ -0,0 +1,122 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ian McGreer <mcgreer@netscape.com>
+ * Javier Delgadillo <javi@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTTRUST_H_
+#define CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTTRUST_H_
+
+#include <certt.h>
+#include <certdb.h>
+
+/*
+ * nsNSSCertTrust
+ *
+ * Class for maintaining trust flags for an NSS certificate.
+ */
+class nsNSSCertTrust
+{
+public:
+ nsNSSCertTrust();
+ nsNSSCertTrust(unsigned int ssl, unsigned int email, unsigned int objsign);
+ nsNSSCertTrust(CERTCertTrust *t);
+ virtual ~nsNSSCertTrust();
+
+ /* query */
+ PRBool HasAnyCA();
+ PRBool HasAnyUser();
+ PRBool HasCA(PRBool checkSSL = PR_TRUE,
+ PRBool checkEmail = PR_TRUE,
+ PRBool checkObjSign = PR_TRUE);
+ PRBool HasPeer(PRBool checkSSL = PR_TRUE,
+ PRBool checkEmail = PR_TRUE,
+ PRBool checkObjSign = PR_TRUE);
+ PRBool HasUser(PRBool checkSSL = PR_TRUE,
+ PRBool checkEmail = PR_TRUE,
+ PRBool checkObjSign = PR_TRUE);
+ PRBool HasTrustedCA(PRBool checkSSL = PR_TRUE,
+ PRBool checkEmail = PR_TRUE,
+ PRBool checkObjSign = PR_TRUE);
+ PRBool HasTrustedPeer(PRBool checkSSL = PR_TRUE,
+ PRBool checkEmail = PR_TRUE,
+ PRBool checkObjSign = PR_TRUE);
+
+ /* common defaults */
+ /* equivalent to "c,c,c" */
+ void SetValidCA();
+ /* equivalent to "C,C,C" */
+ void SetTrustedServerCA();
+ /* equivalent to "CT,CT,CT" */
+ void SetTrustedCA();
+ /* equivalent to "p,," */
+ void SetValidServerPeer();
+ /* equivalent to "p,p,p" */
+ void SetValidPeer();
+ /* equivalent to "P,P,P" */
+ void SetTrustedPeer();
+ /* equivalent to "u,u,u" */
+ void SetUser();
+
+ /* general setters */
+ /* read: "p, P, c, C, T, u, w" */
+ void SetSSLTrust(PRBool peer, PRBool tPeer,
+ PRBool ca, PRBool tCA, PRBool tClientCA,
+ PRBool user, PRBool warn);
+
+ void SetEmailTrust(PRBool peer, PRBool tPeer,
+ PRBool ca, PRBool tCA, PRBool tClientCA,
+ PRBool user, PRBool warn);
+
+ void SetObjSignTrust(PRBool peer, PRBool tPeer,
+ PRBool ca, PRBool tCA, PRBool tClientCA,
+ PRBool user, PRBool warn);
+
+ /* set c <--> CT */
+ void AddCATrust(PRBool ssl, PRBool email, PRBool objSign);
+ /* set p <--> P */
+ void AddPeerTrust(PRBool ssl, PRBool email, PRBool objSign);
+
+ /* get it (const?) (shallow?) */
+ CERTCertTrust * GetTrust() { return &mTrust; }
+
+private:
+ void addTrust(unsigned int *t, unsigned int v);
+ void removeTrust(unsigned int *t, unsigned int v);
+ PRBool hasTrust(unsigned int t, unsigned int v);
+ CERTCertTrust mTrust;
+};
+
+#endif // CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTTRUST_H_