diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-20 22:14:07 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-20 22:14:07 +0000 |
commit | 1e507001a1f4b7e9f96ad4faffd0448a586ac304 (patch) | |
tree | 3981374091abf45e8ca46a64e678efadc7c1ab38 /chrome | |
parent | d64b07bf98e4f27da4c22da6c615b75d4b2e16bc (diff) | |
download | chromium_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.cc | 328 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp | 18 | ||||
-rw-r--r-- | chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h | 13 | ||||
-rw-r--r-- | chrome/third_party/mozilla_security_manager/nsNSSCertTrust.cpp | 365 | ||||
-rw-r--r-- | chrome/third_party/mozilla_security_manager/nsNSSCertTrust.h | 122 |
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_ |