diff options
author | Chris Toshok <toshok@ximian.com> | 2003-11-13 10:23:52 +0800 |
---|---|---|
committer | Chris Toshok <toshok@src.gnome.org> | 2003-11-13 10:23:52 +0800 |
commit | bdba680ed59ee12b4bdcdae2d5a6c3e8cc59daea (patch) | |
tree | 18089837a8fe8eb029233dac94a8f5a06d9ea39b | |
parent | 7e734202c2be76070d5f9a0af821f03191aaf25e (diff) | |
download | gsoc2013-evolution-bdba680ed59ee12b4bdcdae2d5a6c3e8cc59daea.tar gsoc2013-evolution-bdba680ed59ee12b4bdcdae2d5a6c3e8cc59daea.tar.gz gsoc2013-evolution-bdba680ed59ee12b4bdcdae2d5a6c3e8cc59daea.tar.bz2 gsoc2013-evolution-bdba680ed59ee12b4bdcdae2d5a6c3e8cc59daea.tar.lz gsoc2013-evolution-bdba680ed59ee12b4bdcdae2d5a6c3e8cc59daea.tar.xz gsoc2013-evolution-bdba680ed59ee12b4bdcdae2d5a6c3e8cc59daea.tar.zst gsoc2013-evolution-bdba680ed59ee12b4bdcdae2d5a6c3e8cc59daea.zip |
implement using the e-cert-trust foo. (e_cert_get_email): implement.
2003-11-12 Chris Toshok <toshok@ximian.com>
* lib/e-cert.c (e_cert_get_cert_type): implement using the
e-cert-trust foo.
(e_cert_get_email): implement.
* lib/e-cert.h: add UNKNOWN cert type.
* gui/smime-ui.glade: fix capitalization of "Import" on the
contact certificate page.
* gui/certificate-manager.c (import_contact): new function.
implement email cert importing.
(delete_contact): new function.
(unload_certs): implement for E_CERT_CONTACT.
(certificate_manager_config_control_new): get the contact cert
action buttons from libglade.
* lib/e-cert-db.c (handle_ca_cert_download): mostly implement the
trust settings correctly. this still needs work pending the CA
trust dialog's completion.
(e_cert_db_delete_cert): fix the ifdef'ed code.
(e_cert_db_import_user_cert): remove the ifdef'ed body of this,
since it was copied from the CA code.
* lib/Makefile.am (libessmime_la_SOURCES): add e-cert-trust.[ch]
* lib/e-cert-trust.[ch]: new files, basically c&p nsNSSCertTrust
from mozilla's PSM.
svn path=/trunk/; revision=23308
-rw-r--r-- | smime/ChangeLog | 30 | ||||
-rw-r--r-- | smime/gui/certificate-manager.c | 144 | ||||
-rw-r--r-- | smime/gui/smime-ui.glade | 2 | ||||
-rw-r--r-- | smime/lib/Makefile.am | 2 | ||||
-rw-r--r-- | smime/lib/e-cert-db.c | 168 | ||||
-rw-r--r-- | smime/lib/e-cert-trust.c | 418 | ||||
-rw-r--r-- | smime/lib/e-cert-trust.h | 86 | ||||
-rw-r--r-- | smime/lib/e-cert.c | 25 | ||||
-rw-r--r-- | smime/lib/e-cert.h | 3 |
9 files changed, 776 insertions, 102 deletions
diff --git a/smime/ChangeLog b/smime/ChangeLog index 181825ad3f..c17373e393 100644 --- a/smime/ChangeLog +++ b/smime/ChangeLog @@ -1,3 +1,33 @@ +2003-11-12 Chris Toshok <toshok@ximian.com> + + * lib/e-cert.c (e_cert_get_cert_type): implement using the + e-cert-trust foo. + (e_cert_get_email): implement. + + * lib/e-cert.h: add UNKNOWN cert type. + + * gui/smime-ui.glade: fix capitalization of "Import" on the + contact certificate page. + + * gui/certificate-manager.c (import_contact): new function. + implement email cert importing. + (delete_contact): new function. + (unload_certs): implement for E_CERT_CONTACT. + (certificate_manager_config_control_new): get the contact cert + action buttons from libglade. + + * lib/e-cert-db.c (handle_ca_cert_download): mostly implement the + trust settings correctly. this still needs work pending the CA + trust dialog's completion. + (e_cert_db_delete_cert): fix the ifdef'ed code. + (e_cert_db_import_user_cert): remove the ifdef'ed body of this, + since it was copied from the CA code. + + * lib/Makefile.am (libessmime_la_SOURCES): add e-cert-trust.[ch] + + * lib/e-cert-trust.[ch]: new files, basically c&p nsNSSCertTrust + from mozilla's PSM. + 2003-11-11 Chris Toshok <toshok@ximian.com> * tests/import-cert.c (main): don't init NSS here. it's done in diff --git a/smime/gui/certificate-manager.c b/smime/gui/certificate-manager.c index e49617a2db..48f9ef38b1 100644 --- a/smime/gui/certificate-manager.c +++ b/smime/gui/certificate-manager.c @@ -55,6 +55,10 @@ typedef struct { GtkWidget *contactcerts_treeview; GtkTreeStore *contactcerts_treemodel; GHashTable *contactcerts_root_hash; + GtkWidget *view_contact_button; + GtkWidget *edit_contact_button; + GtkWidget *import_contact_button; + GtkWidget *delete_contact_button; GtkWidget *authoritycerts_treeview; GtkTreeStore *authoritycerts_treemodel; @@ -187,15 +191,78 @@ initialize_yourcerts_ui (CertificateManagerData *cfm) } static void +import_contact (GtkWidget *widget, CertificateManagerData *cfm) +{ + GtkWidget *filesel = gtk_file_selection_new (_("Select a cert to import...")); + + if (GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (filesel))) { + const char *filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (filesel)); + + if (e_cert_db_import_certs_from_file (e_cert_db_peek (), + filename, + E_CERT_CONTACT, + NULL)) { + + /* there's no telling how many certificates were added during the import, + so we blow away the contact cert display and regenerate it. */ + unload_certs (cfm, E_CERT_CONTACT); + load_certs (cfm, E_CERT_CONTACT, add_contact_cert); + } + } + + gtk_widget_destroy (filesel); +} + +static void +delete_contact (GtkWidget *widget, CertificateManagerData *cfm) +{ + GtkTreeIter iter; + + if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW(cfm->contactcerts_treeview)), + NULL, + &iter)) { + ECert *cert; + + gtk_tree_model_get (GTK_TREE_MODEL (cfm->contactcerts_treemodel), + &iter, + 3, &cert, + -1); + + if (cert) { + printf ("DELETE\n"); + e_cert_db_delete_cert (e_cert_db_peek (), cert); + gtk_tree_store_remove (cfm->contactcerts_treemodel, + &iter); + + /* we need two unrefs here, one to unref the + gtk_tree_model_get above, and one to unref + the initial ref when we created the cert + and added it to the tree */ + g_object_unref (cert); + g_object_unref (cert); + } + } + +} + +static void contactcerts_selection_changed (GtkTreeSelection *selection, CertificateManagerData *cfm) { -#if 0 handle_selection_changed (gtk_tree_view_get_selection (GTK_TREE_VIEW(cfm->contactcerts_treeview)), - 1 /* XXX */, - NULL, - NULL, - NULL); -#endif + 3, + cfm->view_contact_button, + cfm->edit_contact_button, + cfm->delete_contact_button); +} + +static GtkTreeStore* +create_contactcerts_treemodel (void) +{ + return gtk_tree_store_new (4, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_OBJECT); } static void @@ -222,12 +289,6 @@ initialize_contactcerts_ui (CertificateManagerData *cfm) "text", 2, NULL)); - cfm->contactcerts_treemodel = gtk_tree_store_new (3, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_OBJECT); - gtk_tree_view_set_model (GTK_TREE_VIEW (cfm->contactcerts_treeview), GTK_TREE_MODEL (cfm->contactcerts_treemodel)); @@ -235,6 +296,13 @@ initialize_contactcerts_ui (CertificateManagerData *cfm) selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cfm->contactcerts_treeview)); g_signal_connect (selection, "changed", G_CALLBACK (contactcerts_selection_changed), cfm); + + if (cfm->import_contact_button) + g_signal_connect (cfm->import_contact_button, "clicked", G_CALLBACK (import_contact), cfm); + + if (cfm->delete_contact_button) + g_signal_connect (cfm->delete_contact_button, "clicked", G_CALLBACK (delete_contact), cfm); + } static gint @@ -400,7 +468,40 @@ add_user_cert (CertificateManagerData *cfm, ECert *cert) static void add_contact_cert (CertificateManagerData *cfm, ECert *cert) { - /* nothing yet */ + GtkTreeIter iter; + GtkTreeIter *parent_iter = NULL; + const char *organization = e_cert_get_org (cert); + + if (organization) { + parent_iter = g_hash_table_lookup (cfm->contactcerts_root_hash, organization); + if (!parent_iter) { + /* create a new toplevel node */ + gtk_tree_store_append (GTK_TREE_STORE (cfm->contactcerts_treemodel), &iter, NULL); + + gtk_tree_store_set (GTK_TREE_STORE (cfm->contactcerts_treemodel), &iter, + 0, organization, -1); + + /* now copy it off into parent_iter and insert it into + the hashtable */ + parent_iter = gtk_tree_iter_copy (&iter); + g_hash_table_insert (cfm->contactcerts_root_hash, g_strdup (organization), parent_iter); + } + } + + gtk_tree_store_append (GTK_TREE_STORE (cfm->contactcerts_treemodel), &iter, parent_iter); + + if (e_cert_get_cn (cert)) + gtk_tree_store_set (GTK_TREE_STORE (cfm->contactcerts_treemodel), &iter, + 0, e_cert_get_cn (cert), + 1, e_cert_get_email (cert), + 3, cert, + -1); + else + gtk_tree_store_set (GTK_TREE_STORE (cfm->contactcerts_treemodel), &iter, + 0, e_cert_get_nickname (cert), + 1, e_cert_get_email (cert), + 3, cert, + -1); } static void @@ -461,6 +562,15 @@ unload_certs (CertificateManagerData *cfm, case E_CERT_USER: break; case E_CERT_CONTACT: + cfm->contactcerts_treemodel = create_contactcerts_treemodel (); + gtk_tree_view_set_model (GTK_TREE_VIEW (cfm->contactcerts_treeview), + GTK_TREE_MODEL (cfm->contactcerts_treemodel)); + + if (cfm->contactcerts_root_hash) + g_hash_table_destroy (cfm->contactcerts_root_hash); + + cfm->contactcerts_root_hash = g_hash_table_new_full (g_str_hash, g_str_equal, + destroy_key, destroy_value); break; case E_CERT_SITE: break; @@ -477,6 +587,9 @@ unload_certs (CertificateManagerData *cfm, break; + case E_CERT_UNKNOWN: + /* nothing to do here */ + break; } } @@ -539,6 +652,11 @@ certificate_manager_config_control_new (void) cfm_data->import_your_button = glade_xml_get_widget (cfm_data->gui, "your-import-button"); cfm_data->delete_your_button = glade_xml_get_widget (cfm_data->gui, "your-delete-button"); + cfm_data->view_contact_button = glade_xml_get_widget (cfm_data->gui, "contact-view-button"); + cfm_data->edit_contact_button = glade_xml_get_widget (cfm_data->gui, "contact-edit-button"); + cfm_data->import_contact_button = glade_xml_get_widget (cfm_data->gui, "contact-import-button"); + cfm_data->delete_contact_button = glade_xml_get_widget (cfm_data->gui, "contact-delete-button"); + cfm_data->view_ca_button = glade_xml_get_widget (cfm_data->gui, "authority-view-button"); cfm_data->edit_ca_button = glade_xml_get_widget (cfm_data->gui, "authority-edit-button"); cfm_data->import_ca_button = glade_xml_get_widget (cfm_data->gui, "authority-import-button"); diff --git a/smime/gui/smime-ui.glade b/smime/gui/smime-ui.glade index 338e927470..6870aac384 100644 --- a/smime/gui/smime-ui.glade +++ b/smime/gui/smime-ui.glade @@ -1512,7 +1512,7 @@ <property name="visible">True</property> <property name="can_default">True</property> <property name="can_focus">True</property> - <property name="label" translatable="yes">import</property> + <property name="label" translatable="yes">Import</property> <property name="use_underline">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> </widget> diff --git a/smime/lib/Makefile.am b/smime/lib/Makefile.am index 260238ba35..07093ef5c9 100644 --- a/smime/lib/Makefile.am +++ b/smime/lib/Makefile.am @@ -22,5 +22,7 @@ noinst_LTLIBRARIES = libessmime.la libessmime_la_SOURCES = \ e-cert.c \ e-cert.h \ + e-cert-trust.c \ + e-cert-trust.h \ e-cert-db.c \ e-cert-db.h diff --git a/smime/lib/e-cert-db.c b/smime/lib/e-cert-db.c index 8e98124a14..02959f3505 100644 --- a/smime/lib/e-cert-db.c +++ b/smime/lib/e-cert-db.c @@ -55,7 +55,15 @@ * */ +/* XXX toshok why oh *why* god WHY did they do this? no fucking + sense */ +/* private NSS defines used by PSM */ +/* (must be declated before cert.h) */ +#define CERT_NewTempCertificate __CERT_NewTempCertificate +#define CERT_AddTempCertToPerm __CERT_AddTempCertToPerm + #include "e-cert-db.h" +#include "e-cert-trust.h" #include "nss.h" #include "pk11func.h" @@ -187,12 +195,12 @@ e_cert_db_find_cert_by_nickname (ECertDB *certdb, const char *nickname, GError **error) { - // nsNSSShutDownPreventionLock locker; + /* nsNSSShutDownPreventionLock locker;*/ CERTCertificate *cert = NULL; - //PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting \"%s\"\n", asciiname)); + /*PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting \"%s\"\n", asciiname));*/ #if 0 - // what it should be, but for now... + /* what it should be, but for now...*/ if (aToken) { cert = PK11_FindCertFromNickname(asciiname, NULL); } else { @@ -206,7 +214,7 @@ e_cert_db_find_cert_by_nickname (ECertDB *certdb, if (cert) { - // PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("got it\n")); + /* PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("got it\n"));*/ ECert *ecert = e_cert_new (cert); return ecert; } @@ -222,7 +230,7 @@ e_cert_db_find_cert_by_key (ECertDB *certdb, GError **error) { #if 0 - // nsNSSShutDownPreventionLock locker; + /* nsNSSShutDownPreventionLock locker;*/ SECItem keyItem = {siBuffer, NULL, 0}; SECItem *dummy; CERTIssuerAndSN issuerSN; @@ -237,11 +245,11 @@ e_cert_db_find_cert_by_key (ECertDB *certdb, dummy = NSSBase64_DecodeBuffer(NULL, &keyItem, db_key, (PRUint32)PL_strlen(db_key)); - // someday maybe we can speed up the search using the moduleID and slotID + /* someday maybe we can speed up the search using the moduleID and slotID*/ moduleID = NS_NSS_GET_LONG(keyItem.data); slotID = NS_NSS_GET_LONG(&keyItem.data[NS_NSS_LONG]); - // build the issuer/SN structure + /8 build the issuer/SN structure*/ issuerSN.serialNumber.len = NS_NSS_GET_LONG(&keyItem.data[NS_NSS_LONG*2]); issuerSN.derIssuer.len = NS_NSS_GET_LONG(&keyItem.data[NS_NSS_LONG*3]); issuerSN.serialNumber.data= &keyItem.data[NS_NSS_LONG*4]; @@ -441,6 +449,7 @@ handle_ca_cert_download(GList *certs, GError **error) gboolean allow; char *nickname; SECStatus srv; + CERTCertTrust trust; if (!_confirm_download_ca_cert (certToShow, &trustBits, &allow)) { /* XXX gerror */ @@ -452,23 +461,28 @@ handle_ca_cert_download(GList *certs, GError **error) return FALSE; } - //PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("trust is %d\n", trustBits)); + /*PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("trust is %d\n", trustBits));*/ nickname = CERT_MakeCANickname(tmpCert); - //PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Created nick \"%s\"\n", nickname.get())); - -#if 0 - nsNSSCertTrust trust; - trust.SetValidCA(); - trust.AddCATrust(trustBits & nsIX509CertDB::TRUSTED_SSL, - trustBits & nsIX509CertDB::TRUSTED_EMAIL, - trustBits & nsIX509CertDB::TRUSTED_OBJSIGN); + /*PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Created nick \"%s\"\n", nickname.get()));*/ + + e_cert_trust_init (&trust); + e_cert_trust_set_valid_ca (&trust); + e_cert_trust_add_ca_trust (&trust, +#if 1 + /* XXX we need that ui working i guess. */ + 0, 0, 0 +#else + trustBits & nsIX509CertDB::TRUSTED_SSL, + trustBits & nsIX509CertDB::TRUSTED_EMAIL, + trustBits & nsIX509CertDB::TRUSTED_OBJSIGN #endif +); srv = CERT_AddTempCertToPerm(tmpCert, nickname, - /*XXX trust.GetTrust()*/ 0); + &trust); if (srv != SECSuccess) { /* XXX gerror */ @@ -479,9 +493,9 @@ handle_ca_cert_download(GList *certs, GError **error) /* Now it's time to add the rest of the certs we just downloaded. Since we didn't prompt the user about any of these certs, we won't set any trust bits for them. */ - nsNSSCertTrust defaultTrust; - defaultTrust.SetValidCA(); - defaultTrust.AddCATrust(0,0,0); + e_cert_trust_init (&trust); + e_cert_trust_set_valid_ca (&trust); + e_cert_trusts_add_ca_trust (&trust, 0, 0, 0); for (PRUint32 i=0; i<numCerts; i++) { if (i == selCertIndex) continue; @@ -494,7 +508,7 @@ handle_ca_cert_download(GList *certs, GError **error) if (!tmpCert2) { NS_ASSERTION(0, "Couldn't create temp cert from DER blob\n"); - continue; // Let's try to import the rest of 'em + continue; /* Let's try to import the rest of 'em */ } nickname.Adopt(CERT_MakeCANickname(tmpCert2)); CERT_AddTempCertToPerm(tmpCert2, NS_CONST_CAST(char*,nickname.get()), @@ -511,8 +525,8 @@ gboolean e_cert_db_delete_cert (ECertDB *certdb, ECert *ecert) { - // nsNSSShutDownPreventionLock locker; - // nsNSSCertificate *nssCert = NS_STATIC_CAST(nsNSSCertificate*, aCert); + /* nsNSSShutDownPreventionLock locker; + nsNSSCertificate *nssCert = NS_STATIC_CAST(nsNSSCertificate*, aCert); */ CERTCertificate *cert; SECStatus srv = SECSuccess; @@ -529,16 +543,14 @@ e_cert_db_delete_cert (ECertDB *certdb, want to do that with user certs, because a user may re-store the cert onto the card again at which point we *will* want to trust that cert if it chains up properly. */ -#if 0 - nsNSSCertTrust trust(0, 0, 0); + CERTCertTrust trust; + + e_cert_trust_init_with_values (&trust, 0, 0, 0); srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), - cert, trust.GetTrust()); -#endif + cert, &trust); } -#if 0 - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("cert deleted: %d", srv)); -#endif + /*PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("cert deleted: %d", srv));*/ return (srv) ? FALSE : TRUE; } @@ -582,7 +594,7 @@ e_cert_db_import_certs (ECertDB *certdb, rv = handle_ca_cert_download(certs, error); break; default: - // We only deal with import CA certs in this method currently. + /* We only deal with import CA certs in this method currently.*/ /* XXX gerror */ PORT_FreeArena(arena, PR_FALSE); rv = FALSE; @@ -599,73 +611,65 @@ e_cert_db_import_email_cert (ECertDB *certdb, char *data, guint32 length, GError **error) { -} + /*nsNSSShutDownPreventionLock locker;*/ + SECStatus srv = SECFailure; + gboolean rv = TRUE; + CERTCertificate * cert; + SECItem **rawCerts; + int numcerts; + int i; + PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + CERTDERCerts *certCollection = e_cert_db_get_certs_from_package (arena, data, length); -gboolean -e_cert_db_import_user_cert (ECertDB *certdb, - char *data, guint32 length, - GError **error) -{ -#if 0 - /* nsNSSShutDownPreventionLock locker;*/ - PK11SlotInfo *slot; - char * nickname = NULL; - gboolean rv = FALSE; - int numCACerts; - SECItem *CACerts; - CERTDERCerts * collectArgs; - CERTCertificate * cert=NULL; - - collectArgs = e_cert_db_get_certs_from_package(data, length); - if (!collectArgs) { - goto loser; + if (!certCollection) { + /* XXX g_error */ + + PORT_FreeArena(arena, PR_FALSE); + return FALSE; } - cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), collectArgs->rawCerts, + cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), certCollection->rawCerts, (char *)NULL, PR_FALSE, PR_TRUE); if (!cert) { + /* XXX g_error */ + rv = FALSE; goto loser; } - - slot = PK11_KeyForCertExists(cert, NULL, NULL); - if ( slot == NULL ) { + numcerts = certCollection->numcerts; + rawCerts = (SECItem **) PORT_Alloc(sizeof(SECItem *) * numcerts); + if ( !rawCerts ) { + /* XXX g_error */ + rv = FALSE; goto loser; } - PK11_FreeSlot(slot); - /* pick a nickname for the cert */ - if (cert->nickname) { - /* sigh, we need a call to look up other certs with this subject and - * identify nicknames from them. We can no longer walk down internal - * database structures rjr */ - nickname = cert->nickname; + for ( i = 0; i < numcerts; i++ ) { + rawCerts[i] = &certCollection->rawCerts[i]; } - else { - g_assert_not_reached (); - /* nickname = default_nickname(cert, NULL); */ - } - - /* user wants to import the cert */ - slot = PK11_ImportCertForKey(cert, nickname, NULL); - if (!slot) { + + srv = CERT_ImportCerts(CERT_GetDefaultCertDB(), certUsageEmailSigner, + numcerts, rawCerts, NULL, PR_TRUE, PR_FALSE, + NULL); + if ( srv != SECSuccess ) { + /* XXX g_error */ + rv = FALSE; goto loser; } - PK11_FreeSlot(slot); - numCACerts = collectArgs->numcerts - 1; - - if (numCACerts) { - CACerts = collectArgs->rawCerts+1; - if ( ! CERT_ImportCAChain(CACerts, numCACerts, certUsageUserCertImport) ) { - rv = TRUE; - } - } - + srv = CERT_SaveSMimeProfile(cert, NULL, NULL); + PORT_Free(rawCerts); loser: - if ( cert ) { + if (cert) CERT_DestroyCertificate(cert); - } + if (arena) + PORT_FreeArena(arena, PR_TRUE); return rv; -#endif +} + +gboolean +e_cert_db_import_user_cert (ECertDB *certdb, + char *data, guint32 length, + GError **error) +{ } gboolean diff --git a/smime/lib/e-cert-trust.c b/smime/lib/e-cert-trust.c new file mode 100644 index 0000000000..7386a88963 --- /dev/null +++ b/smime/lib/e-cert-trust.c @@ -0,0 +1,418 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Chris Toshok <toshok@ximian.com> + * + * Copyright (C) 2003 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. + * + */ + +/* this code is pretty much cut&pasted and renamed from mozilla. + here's their copyright/blurb */ + +/* + * 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 Netscape are + * Copyright (C) 2000 Netscape Communications Corporation. 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 the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + * + */ + +#include "e-cert-trust.h" + +void +e_cert_trust_init (CERTCertTrust *trust) +{ + memset(trust, 0, sizeof(CERTCertTrust)); +} + +void +e_cert_trust_init_with_values (CERTCertTrust *trust, + unsigned int ssl, + unsigned int email, + unsigned int objsign) +{ + memset(trust, 0, sizeof(CERTCertTrust)); + e_cert_trust_add_trust(&trust->sslFlags, ssl); + e_cert_trust_add_trust(&trust->emailFlags, email); + e_cert_trust_add_trust(&trust->objectSigningFlags, objsign); +} + +void +e_cert_trust_copy (CERTCertTrust *trust, CERTCertTrust *t) +{ + if (t) + memcpy(trust, t, sizeof(CERTCertTrust)); + else + memset(trust, 0, sizeof(CERTCertTrust)); +} + +void +e_cert_trust_add_ca_trust (CERTCertTrust *trust, PRBool ssl, PRBool email, PRBool objSign) +{ + if (ssl) { + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_TRUSTED_CA); + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_TRUSTED_CLIENT_CA); + } + if (email) { + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_TRUSTED_CA); + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_TRUSTED_CLIENT_CA); + } + if (objSign) { + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_TRUSTED_CA); + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA); + } +} + +void +e_cert_trust_add_peer_trust (CERTCertTrust *trust, PRBool ssl, PRBool email, PRBool objSign) +{ + if (ssl) + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_TRUSTED); + if (email) + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_TRUSTED); + if (objSign) + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_TRUSTED); +} + +void +e_cert_trust_set_ssl_trust (CERTCertTrust *trust, + PRBool peer, PRBool tPeer, + PRBool ca, PRBool tCA, PRBool tClientCA, + PRBool user, PRBool warn) +{ + trust->sslFlags = 0; + if (peer || tPeer) + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_VALID_PEER); + if (tPeer) + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_TRUSTED); + if (ca || tCA) + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_VALID_CA); + if (tClientCA) + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_TRUSTED_CLIENT_CA); + if (tCA) + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_TRUSTED_CA); + if (user) + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_USER); + if (warn) + e_cert_trust_add_trust(&trust->sslFlags, CERTDB_SEND_WARN); +} + +void +e_cert_trust_set_email_trust (CERTCertTrust *trust, + PRBool peer, PRBool tPeer, + PRBool ca, PRBool tCA, PRBool tClientCA, + PRBool user, PRBool warn) +{ + trust->emailFlags = 0; + if (peer || tPeer) + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_VALID_PEER); + if (tPeer) + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_TRUSTED); + if (ca || tCA) + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_VALID_CA); + if (tClientCA) + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_TRUSTED_CLIENT_CA); + if (tCA) + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_TRUSTED_CA); + if (user) + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_USER); + if (warn) + e_cert_trust_add_trust(&trust->emailFlags, CERTDB_SEND_WARN); +} + +void +e_cert_trust_set_objsign_trust (CERTCertTrust *trust, + PRBool peer, PRBool tPeer, + PRBool ca, PRBool tCA, PRBool tClientCA, + PRBool user, PRBool warn) +{ + trust->objectSigningFlags = 0; + if (peer || tPeer) + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_VALID_PEER); + if (tPeer) + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_TRUSTED); + if (ca || tCA) + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_VALID_CA); + if (tClientCA) + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA); + if (tCA) + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_TRUSTED_CA); + if (user) + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_USER); + if (warn) + e_cert_trust_add_trust(&trust->objectSigningFlags, CERTDB_SEND_WARN); +} + +void +e_cert_trust_set_valid_ca (CERTCertTrust *trust) +{ + e_cert_trust_set_ssl_trust (trust, + PR_FALSE, PR_FALSE, + PR_TRUE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_email_trust (trust, + PR_FALSE, PR_FALSE, + PR_TRUE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_objsign_trust (trust, + PR_FALSE, PR_FALSE, + PR_TRUE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); +} + +void +e_cert_trust_set_trusted_server_ca (CERTCertTrust *trust) +{ + e_cert_trust_set_ssl_trust (trust, + PR_FALSE, PR_FALSE, + PR_TRUE, PR_TRUE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_email_trust (trust, + PR_FALSE, PR_FALSE, + PR_TRUE, PR_TRUE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_objsign_trust (trust, + PR_FALSE, PR_FALSE, + PR_TRUE, PR_TRUE, PR_FALSE, + PR_FALSE, PR_FALSE); +} + +void +e_cert_trust_set_trusted_ca (CERTCertTrust *trust) +{ + e_cert_trust_set_ssl_trust (trust, + PR_FALSE, PR_FALSE, + PR_TRUE, PR_TRUE, PR_TRUE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_email_trust (trust, + PR_FALSE, PR_FALSE, + PR_TRUE, PR_TRUE, PR_TRUE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_objsign_trust (trust, + PR_FALSE, PR_FALSE, + PR_TRUE, PR_TRUE, PR_TRUE, + PR_FALSE, PR_FALSE); +} + +void +e_cert_trust_set_valid_peer (CERTCertTrust *trust) +{ + e_cert_trust_set_ssl_trust (trust, + PR_TRUE, PR_FALSE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_email_trust (trust, + PR_TRUE, PR_FALSE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_objsign_trust (trust, + PR_TRUE, PR_FALSE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); +} + +void +e_cert_trust_set_valid_server_peer (CERTCertTrust *trust) +{ + e_cert_trust_set_ssl_trust (trust, + PR_TRUE, PR_FALSE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_email_trust (trust, + PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_objsign_trust (trust, + PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); +} + +void +e_cert_trust_set_trusted_peer (CERTCertTrust *trust) +{ + e_cert_trust_set_ssl_trust (trust, + PR_TRUE, PR_TRUE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_email_trust (trust, + PR_TRUE, PR_TRUE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); + e_cert_trust_set_objsign_trust (trust, + PR_TRUE, PR_TRUE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE); +} + +void +e_cert_trust_set_user (CERTCertTrust *trust) +{ + e_cert_trust_set_ssl_trust (trust, + PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_TRUE, PR_FALSE); + e_cert_trust_set_email_trust (trust, + PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_TRUE, PR_FALSE); + e_cert_trust_set_objsign_trust (trust, + PR_FALSE, PR_FALSE, + PR_FALSE, PR_FALSE, PR_FALSE, + PR_TRUE, PR_FALSE); +} + +PRBool +e_cert_trust_has_any_ca (CERTCertTrust *trust) +{ + if (e_cert_trust_has_trust(trust->sslFlags, CERTDB_VALID_CA) || + e_cert_trust_has_trust(trust->emailFlags, CERTDB_VALID_CA) || + e_cert_trust_has_trust(trust->objectSigningFlags, CERTDB_VALID_CA)) + return PR_TRUE; + return PR_FALSE; +} + +PRBool +e_cert_trust_has_ca (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign) +{ + if (checkSSL && !e_cert_trust_has_trust(trust->sslFlags, CERTDB_VALID_CA)) + return PR_FALSE; + if (checkEmail && !e_cert_trust_has_trust(trust->emailFlags, CERTDB_VALID_CA)) + return PR_FALSE; + if (checkObjSign && !e_cert_trust_has_trust(trust->objectSigningFlags, CERTDB_VALID_CA)) + return PR_FALSE; + return PR_TRUE; +} + +PRBool +e_cert_trust_has_peer (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign) +{ + if (checkSSL && !e_cert_trust_has_trust(trust->sslFlags, CERTDB_VALID_PEER)) + return PR_FALSE; + if (checkEmail && !e_cert_trust_has_trust(trust->emailFlags, CERTDB_VALID_PEER)) + return PR_FALSE; + if (checkObjSign && !e_cert_trust_has_trust(trust->objectSigningFlags, CERTDB_VALID_PEER)) + return PR_FALSE; + return PR_TRUE; +} + +PRBool +e_cert_trust_has_any_user (CERTCertTrust *trust) +{ + if (e_cert_trust_has_trust(trust->sslFlags, CERTDB_USER) || + e_cert_trust_has_trust(trust->emailFlags, CERTDB_USER) || + e_cert_trust_has_trust(trust->objectSigningFlags, CERTDB_USER)) + return PR_TRUE; + return PR_FALSE; +} + +PRBool +e_cert_trust_has_user (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign) +{ + if (checkSSL && !e_cert_trust_has_trust(trust->sslFlags, CERTDB_USER)) + return PR_FALSE; + if (checkEmail && !e_cert_trust_has_trust(trust->emailFlags, CERTDB_USER)) + return PR_FALSE; + if (checkObjSign && !e_cert_trust_has_trust(trust->objectSigningFlags, CERTDB_USER)) + return PR_FALSE; + return PR_TRUE; +} + +PRBool +e_cert_trust_has_trusted_ca (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign) +{ + if (checkSSL && !(e_cert_trust_has_trust(trust->sslFlags, CERTDB_TRUSTED_CA) || + e_cert_trust_has_trust(trust->sslFlags, CERTDB_TRUSTED_CLIENT_CA))) + return PR_FALSE; + if (checkEmail && !(e_cert_trust_has_trust(trust->emailFlags, CERTDB_TRUSTED_CA) || + e_cert_trust_has_trust(trust->emailFlags, CERTDB_TRUSTED_CLIENT_CA))) + return PR_FALSE; + if (checkObjSign && + !(e_cert_trust_has_trust(trust->objectSigningFlags, CERTDB_TRUSTED_CA) || + e_cert_trust_has_trust(trust->objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA))) + return PR_FALSE; + return PR_TRUE; +} + +PRBool +e_cert_trust_has_trusted_peer (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign) +{ + if (checkSSL && !(e_cert_trust_has_trust(trust->sslFlags, CERTDB_TRUSTED))) + return PR_FALSE; + if (checkEmail && !(e_cert_trust_has_trust(trust->emailFlags, CERTDB_TRUSTED))) + return PR_FALSE; + if (checkObjSign && + !(e_cert_trust_has_trust(trust->objectSigningFlags, CERTDB_TRUSTED))) + return PR_FALSE; + return PR_TRUE; +} + +void +e_cert_trust_add_trust (unsigned int *t, unsigned int v) +{ + *t |= v; +} + +PRBool +e_cert_trust_has_trust (unsigned int t, unsigned int v) +{ + return (t & v); +} + diff --git a/smime/lib/e-cert-trust.h b/smime/lib/e-cert-trust.h new file mode 100644 index 0000000000..c55d928019 --- /dev/null +++ b/smime/lib/e-cert-trust.h @@ -0,0 +1,86 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Chris Toshok <toshok@ximian.com> + * + * Copyright (C) 2003 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _E_CERT_TRUST_H_ +#define _E_CERT_TRUST_H_ + +#include <glib.h> +#include <cert.h> +#include <certdb.h> + +G_BEGIN_DECLS + +void e_cert_trust_init (CERTCertTrust *trust); +void e_cert_trust_init_with_values (CERTCertTrust *trust, + unsigned int ssl, + unsigned int email, + unsigned int objsign); +void e_cert_trust_copy (CERTCertTrust *dst_trust, CERTCertTrust *src_trust); +void e_cert_trust_add_ca_trust (CERTCertTrust *trust, PRBool ssl, PRBool email, PRBool objSign); +void e_cert_trust_add_peer_trust (CERTCertTrust *trust, PRBool ssl, PRBool email, PRBool objSign); +void e_cert_trust_set_ssl_trust (CERTCertTrust *trust, + PRBool peer, PRBool tPeer, + PRBool ca, PRBool tCA, PRBool tClientCA, + PRBool user, PRBool warn); +void e_cert_trust_set_email_trust (CERTCertTrust *trust, + PRBool peer, PRBool tPeer, + PRBool ca, PRBool tCA, PRBool tClientCA, + PRBool user, PRBool warn); +void e_cert_trust_set_objsign_trust (CERTCertTrust *trust, + PRBool peer, PRBool tPeer, + PRBool ca, PRBool tCA, PRBool tClientCA, + PRBool user, PRBool warn); +void e_cert_trust_set_valid_ca (CERTCertTrust *trust); +void e_cert_trust_set_trusted_server_ca (CERTCertTrust *trust); +void e_cert_trust_set_trusted_ca (CERTCertTrust *trust); +void e_cert_trust_set_valid_peer (CERTCertTrust *trust); +void e_cert_trust_set_valid_server_peer (CERTCertTrust *trust); +void e_cert_trust_set_trusted_peer (CERTCertTrust *trust); +void e_cert_trust_set_user (CERTCertTrust *trust); +PRBool e_cert_trust_has_any_ca (CERTCertTrust *trust); +PRBool e_cert_trust_has_ca (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign); +PRBool e_cert_trust_has_peer (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign); +PRBool e_cert_trust_has_any_user (CERTCertTrust *trust); +PRBool e_cert_trust_has_user (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign); +PRBool e_cert_trust_has_trusted_ca (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign); +PRBool e_cert_trust_has_trusted_peer (CERTCertTrust *trust, + PRBool checkSSL, + PRBool checkEmail, + PRBool checkObjSign); +void e_cert_trust_add_trust (unsigned int *t, unsigned int v); +PRBool e_cert_trust_has_trust (unsigned int t, unsigned int v); + +G_END_DECLS + +#endif /* _E_CERT_H_ */ diff --git a/smime/lib/e-cert.c b/smime/lib/e-cert.c index 7db638b884..9563468de3 100644 --- a/smime/lib/e-cert.c +++ b/smime/lib/e-cert.c @@ -56,6 +56,7 @@ */ #include "e-cert.h" +#include "e-cert-trust.h" #include "pk11func.h" #include "certdb.h" @@ -219,6 +220,7 @@ e_cert_get_nickname (ECert *cert) const char* e_cert_get_email (ECert *cert) { + return cert->priv->cert->emailAddr; } const char* @@ -269,10 +271,23 @@ e_cert_mark_for_deletion (ECert *cert) } ECertType -e_cert_get_cert_type (ECert *cert) +e_cert_get_cert_type (ECert *ecert) { - if (CERT_IsCACert (cert->priv->cert, NULL)) - return E_CERT_CA; - else /* XXX more here */ - return E_CERT_USER; + const char *nick = e_cert_get_nickname (ecert); + const char *email = e_cert_get_email (ecert); + CERTCertificate *cert = ecert->priv->cert; + + if (nick) { + if (e_cert_trust_has_any_user (cert->trust)) + return E_CERT_USER; + if (e_cert_trust_has_any_ca (cert->trust) + || CERT_IsCACert(cert,NULL)) + return E_CERT_CA; + if (e_cert_trust_has_peer (cert->trust, PR_TRUE, PR_FALSE, PR_FALSE)) + return E_CERT_SITE; + } + if (email && e_cert_trust_has_peer (cert->trust, PR_FALSE, PR_TRUE, PR_FALSE)) + return E_CERT_CONTACT; + + return E_CERT_UNKNOWN; } diff --git a/smime/lib/e-cert.h b/smime/lib/e-cert.h index 06b44f23ad..662d26f849 100644 --- a/smime/lib/e-cert.h +++ b/smime/lib/e-cert.h @@ -41,7 +41,8 @@ typedef enum { E_CERT_CA, E_CERT_CONTACT, E_CERT_SITE, - E_CERT_USER + E_CERT_USER, + E_CERT_UNKNOWN } ECertType; struct _ECert { |