don't init NSS here. it's done in e_cert_db_peek.
2003-11-11 Chris Toshok <toshok@ximian.com> * tests/import-cert.c (main): don't init NSS here. it's done in e_cert_db_peek. * lib/Makefile.am (libessmime_la_SOURCES): add e-cert-db.[ch] * gui/smime-ui.glade: set the initial sensitivity of the buttons here, and add the beginnings of the CA import dialog (where you assign trust levels to it.) * gui/certificate-manager.c (handle_selection_changed): sensitize/desensitize all the various buttons correctly when the GtkTreeView's selection changes. (yourcerts_selection_changed): new, selection change handler for the Your Certs tab. (initialize_yourcerts_ui): hook up the tree selection, and add a model column for the ECert. (contactcerts_selection_changed): new, selection change handler for the Contact Certs tab. (initialize_contactcerts_ui): hook up the tree selection, and add a model column for the ECert. (import_ca): new function. (delete_ca): new function. (authoritycerts_selection_changed): new, selection change handler for the Authority Certs tab. (create_authoritycerts_treemodel): new function for creating the authority cert tree model. the other tabs will eventually use a separate function for this too, as unload_certs gets fleshed out. (initialize_authoritycerts_ui): hook up the tree selection, and add import/delete buttons. (destroy_key): dtor for the keys in our hashes. (destroy_value): dtor for the values in our hashes. (unload_certs): new function. basically destroy/recreate the model and hash for the particular cert type/tab. (load_certs): use e_cert_get_cert_type. (populate_ui): use unload_certs as well as load_certs. (certificate_manager_config_control_new): call e_cert_db_peek ,which will initialize all of NSS. hook up all the widgets from libglade. * lib/e-cert.h: add prototypes for all the new methods, and add the ECertType enum. * lib/e-cert.c (e_cert_dispose): handle deletion from the DB here. (e_cert_new_from_der): new function. (e_cert_get_internal_cert): new function. (e_cert_get_raw_der): new function. (e_cert_get_issuer_name): new (e_cert_get_subject_name): new (e_cert_mark_for_deletion): new (e_cert_get_cert_type): new. (e_cert_is_ca_cert): nuke. * lib/e-cert-db.[ch]: new, partly implemented, derived from mozilla's nsNSSCertificateDB code. svn path=/trunk/; revision=23292
This commit is contained in:
parent
747e7843d1
commit
4e1bce59fa
@ -1,3 +1,60 @@
|
||||
2003-11-11 Chris Toshok <toshok@ximian.com>
|
||||
|
||||
* tests/import-cert.c (main): don't init NSS here. it's done in
|
||||
e_cert_db_peek.
|
||||
|
||||
* lib/Makefile.am (libessmime_la_SOURCES): add e-cert-db.[ch]
|
||||
|
||||
* gui/smime-ui.glade: set the initial sensitivity of the buttons
|
||||
here, and add the beginnings of the CA import dialog (where you
|
||||
assign trust levels to it.)
|
||||
|
||||
* gui/certificate-manager.c (handle_selection_changed):
|
||||
sensitize/desensitize all the various buttons correctly when the
|
||||
GtkTreeView's selection changes.
|
||||
(yourcerts_selection_changed): new, selection change handler for
|
||||
the Your Certs tab.
|
||||
(initialize_yourcerts_ui): hook up the tree selection, and add a
|
||||
model column for the ECert.
|
||||
(contactcerts_selection_changed): new, selection change handler
|
||||
for the Contact Certs tab.
|
||||
(initialize_contactcerts_ui): hook up the tree selection, and add
|
||||
a model column for the ECert.
|
||||
(import_ca): new function.
|
||||
(delete_ca): new function.
|
||||
(authoritycerts_selection_changed): new, selection change handler
|
||||
for the Authority Certs tab.
|
||||
(create_authoritycerts_treemodel): new function for creating the
|
||||
authority cert tree model. the other tabs will eventually use a
|
||||
separate function for this too, as unload_certs gets fleshed out.
|
||||
(initialize_authoritycerts_ui): hook up the tree selection, and
|
||||
add import/delete buttons.
|
||||
(destroy_key): dtor for the keys in our hashes.
|
||||
(destroy_value): dtor for the values in our hashes.
|
||||
(unload_certs): new function. basically destroy/recreate the
|
||||
model and hash for the particular cert type/tab.
|
||||
(load_certs): use e_cert_get_cert_type.
|
||||
(populate_ui): use unload_certs as well as load_certs.
|
||||
(certificate_manager_config_control_new): call e_cert_db_peek
|
||||
,which will initialize all of NSS. hook up all the widgets from
|
||||
libglade.
|
||||
|
||||
* lib/e-cert.h: add prototypes for all the new methods, and add
|
||||
the ECertType enum.
|
||||
|
||||
* lib/e-cert.c (e_cert_dispose): handle deletion from the DB here.
|
||||
(e_cert_new_from_der): new function.
|
||||
(e_cert_get_internal_cert): new function.
|
||||
(e_cert_get_raw_der): new function.
|
||||
(e_cert_get_issuer_name): new
|
||||
(e_cert_get_subject_name): new
|
||||
(e_cert_mark_for_deletion): new
|
||||
(e_cert_get_cert_type): new.
|
||||
(e_cert_is_ca_cert): nuke.
|
||||
|
||||
* lib/e-cert-db.[ch]: new, partly implemented, derived from
|
||||
mozilla's nsNSSCertificateDB code.
|
||||
|
||||
2003-10-30 Chris Toshok <toshok@ximian.com>
|
||||
|
||||
* gui/certificate-manager.h: add boilerplate.
|
||||
|
@ -22,11 +22,7 @@
|
||||
|
||||
#define GLADE_FILE_NAME "smime-ui.glade"
|
||||
|
||||
#include <gtk/gtkcontainer.h>
|
||||
#include <gtk/gtktreeview.h>
|
||||
#include <gtk/gtktreestore.h>
|
||||
#include <gtk/gtktreemodelsort.h>
|
||||
#include <gtk/gtkcellrenderertext.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <libgnome/gnome-i18n.h>
|
||||
|
||||
@ -35,6 +31,7 @@
|
||||
#include "certificate-manager.h"
|
||||
|
||||
#include "e-cert.h"
|
||||
#include "e-cert-db.h"
|
||||
|
||||
#include "nss.h"
|
||||
#include <cms.h>
|
||||
@ -49,6 +46,11 @@ typedef struct {
|
||||
GtkWidget *yourcerts_treeview;
|
||||
GtkTreeStore *yourcerts_treemodel;
|
||||
GHashTable *yourcerts_root_hash;
|
||||
GtkWidget *view_your_button;
|
||||
GtkWidget *backup_your_button;
|
||||
GtkWidget *backup_all_your_button;
|
||||
GtkWidget *import_your_button;
|
||||
GtkWidget *delete_your_button;
|
||||
|
||||
GtkWidget *contactcerts_treeview;
|
||||
GtkTreeStore *contactcerts_treemodel;
|
||||
@ -57,18 +59,72 @@ typedef struct {
|
||||
GtkWidget *authoritycerts_treeview;
|
||||
GtkTreeStore *authoritycerts_treemodel;
|
||||
GHashTable *authoritycerts_root_hash;
|
||||
GtkWidget *view_ca_button;
|
||||
GtkWidget *edit_ca_button;
|
||||
GtkWidget *import_ca_button;
|
||||
GtkWidget *delete_ca_button;
|
||||
|
||||
} CertificateManagerData;
|
||||
|
||||
typedef enum {
|
||||
USER_CERT,
|
||||
CONTACT_CERT,
|
||||
CA_CERT
|
||||
} CertType;
|
||||
typedef void (*AddCertCb)(CertificateManagerData *cfm, ECert *cert);
|
||||
|
||||
static void unload_certs (CertificateManagerData *cfm, ECertType type);
|
||||
static void load_certs (CertificateManagerData *cfm, ECertType type, AddCertCb add_cert);
|
||||
|
||||
static void add_user_cert (CertificateManagerData *cfm, ECert *cert);
|
||||
static void add_contact_cert (CertificateManagerData *cfm, ECert *cert);
|
||||
static void add_ca_cert (CertificateManagerData *cfm, ECert *cert);
|
||||
|
||||
static void
|
||||
handle_selection_changed (GtkTreeSelection *selection,
|
||||
int cert_column,
|
||||
GtkWidget *view_button,
|
||||
GtkWidget *edit_button,
|
||||
GtkWidget *delete_button)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gboolean cert_selected = FALSE;
|
||||
GtkTreeModel *model;
|
||||
|
||||
if (gtk_tree_selection_get_selected (selection,
|
||||
&model,
|
||||
&iter)) {
|
||||
ECert *cert;
|
||||
|
||||
gtk_tree_model_get (model,
|
||||
&iter,
|
||||
cert_column, &cert,
|
||||
-1);
|
||||
|
||||
if (cert) {
|
||||
cert_selected = TRUE;
|
||||
g_object_unref (cert);
|
||||
}
|
||||
}
|
||||
|
||||
if (delete_button)
|
||||
gtk_widget_set_sensitive (delete_button, cert_selected);
|
||||
if (edit_button)
|
||||
gtk_widget_set_sensitive (edit_button, cert_selected);
|
||||
if (view_button)
|
||||
gtk_widget_set_sensitive (view_button, cert_selected);
|
||||
}
|
||||
|
||||
static void
|
||||
yourcerts_selection_changed (GtkTreeSelection *selection, CertificateManagerData *cfm)
|
||||
{
|
||||
handle_selection_changed (gtk_tree_view_get_selection (GTK_TREE_VIEW(cfm->yourcerts_treeview)),
|
||||
4,
|
||||
cfm->view_your_button,
|
||||
cfm->backup_your_button, /* yes yes, not really "edit", it's a hack :) */
|
||||
cfm->delete_your_button);
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_yourcerts_ui (CertificateManagerData *cfm)
|
||||
{
|
||||
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (cfm->yourcerts_treeview),
|
||||
gtk_tree_view_column_new_with_attributes (_("Certificate Name"),
|
||||
@ -94,22 +150,59 @@ initialize_yourcerts_ui (CertificateManagerData *cfm)
|
||||
"text", 3,
|
||||
NULL));
|
||||
|
||||
cfm->yourcerts_treemodel = gtk_tree_store_new (4,
|
||||
cfm->yourcerts_treemodel = gtk_tree_store_new (5,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING);
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (cfm->yourcerts_treeview),
|
||||
GTK_TREE_MODEL (cfm->yourcerts_treemodel));
|
||||
|
||||
cfm->yourcerts_root_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cfm->yourcerts_treeview));
|
||||
g_signal_connect (selection, "changed", G_CALLBACK (yourcerts_selection_changed), cfm);
|
||||
|
||||
if (cfm->import_your_button) {
|
||||
/* g_signal_connect */
|
||||
}
|
||||
|
||||
if (cfm->delete_your_button) {
|
||||
/* g_signal_connect */
|
||||
}
|
||||
|
||||
if (cfm->view_your_button) {
|
||||
/* g_signal_connect */
|
||||
}
|
||||
|
||||
if (cfm->backup_your_button) {
|
||||
/* g_signal_connect */
|
||||
}
|
||||
|
||||
if (cfm->backup_all_your_button) {
|
||||
/* g_signal_connect */
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_contactcerts_ui (CertificateManagerData *cfm)
|
||||
{
|
||||
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (cfm->contactcerts_treeview),
|
||||
gtk_tree_view_column_new_with_attributes (_("Certificate Name"),
|
||||
@ -132,12 +225,16 @@ initialize_contactcerts_ui (CertificateManagerData *cfm)
|
||||
cfm->contactcerts_treemodel = gtk_tree_store_new (3,
|
||||
G_TYPE_STRING,
|
||||
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));
|
||||
|
||||
cfm->contactcerts_root_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cfm->contactcerts_treeview));
|
||||
g_signal_connect (selection, "changed", G_CALLBACK (contactcerts_selection_changed), cfm);
|
||||
}
|
||||
|
||||
static gint
|
||||
@ -159,10 +256,85 @@ iter_string_compare (GtkTreeModel *model,
|
||||
return g_utf8_collate (string1, string2);
|
||||
}
|
||||
|
||||
static void
|
||||
import_ca (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_CA,
|
||||
NULL)) {
|
||||
|
||||
/* there's no telling how many certificates were added during the import,
|
||||
so we blow away the CA cert display and regenerate it. */
|
||||
unload_certs (cfm, E_CERT_CA);
|
||||
load_certs (cfm, E_CERT_CA, add_ca_cert);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_destroy (filesel);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_ca (GtkWidget *widget, CertificateManagerData *cfm)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW(cfm->authoritycerts_treeview)),
|
||||
NULL,
|
||||
&iter)) {
|
||||
ECert *cert;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (cfm->authoritycerts_treemodel),
|
||||
&iter,
|
||||
1, &cert,
|
||||
-1);
|
||||
|
||||
if (cert) {
|
||||
printf ("DELETE\n");
|
||||
e_cert_db_delete_cert (e_cert_db_peek (), cert);
|
||||
gtk_tree_store_remove (cfm->authoritycerts_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
|
||||
authoritycerts_selection_changed (GtkTreeSelection *selection, CertificateManagerData *cfm)
|
||||
{
|
||||
handle_selection_changed (gtk_tree_view_get_selection (GTK_TREE_VIEW(cfm->authoritycerts_treeview)),
|
||||
1,
|
||||
cfm->view_ca_button,
|
||||
cfm->edit_ca_button,
|
||||
cfm->delete_ca_button);
|
||||
}
|
||||
|
||||
static GtkTreeStore*
|
||||
create_authoritycerts_treemodel (void)
|
||||
{
|
||||
return gtk_tree_store_new (2,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_authoritycerts_ui (CertificateManagerData *cfm)
|
||||
{
|
||||
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (cfm->authoritycerts_treeview),
|
||||
gtk_tree_view_column_new_with_attributes (_("Certificate Name"),
|
||||
@ -170,9 +342,6 @@ initialize_authoritycerts_ui (CertificateManagerData *cfm)
|
||||
"text", 0,
|
||||
NULL));
|
||||
|
||||
cfm->authoritycerts_treemodel = gtk_tree_store_new (1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (cfm->authoritycerts_treemodel),
|
||||
0,
|
||||
iter_string_compare, NULL, NULL);
|
||||
@ -181,35 +350,22 @@ initialize_authoritycerts_ui (CertificateManagerData *cfm)
|
||||
0,
|
||||
GTK_SORT_ASCENDING);
|
||||
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (cfm->authoritycerts_treeview),
|
||||
GTK_TREE_MODEL (cfm->authoritycerts_treemodel));
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cfm->authoritycerts_treeview));
|
||||
g_signal_connect (selection, "changed", G_CALLBACK (authoritycerts_selection_changed), cfm);
|
||||
|
||||
cfm->authoritycerts_root_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
if (cfm->import_ca_button)
|
||||
g_signal_connect (cfm->import_ca_button, "clicked", G_CALLBACK (import_ca), cfm);
|
||||
|
||||
if (cfm->delete_ca_button)
|
||||
g_signal_connect (cfm->delete_ca_button, "clicked", G_CALLBACK (delete_ca), cfm);
|
||||
}
|
||||
|
||||
static CertType
|
||||
get_cert_type (ECert *cert)
|
||||
{
|
||||
const char *nick = e_cert_get_nickname (cert);
|
||||
const char *email = e_cert_get_email (cert);
|
||||
|
||||
if (e_cert_is_ca_cert (cert))
|
||||
return CA_CERT;
|
||||
|
||||
/* XXX more stuff in here */
|
||||
else
|
||||
return USER_CERT;
|
||||
}
|
||||
|
||||
typedef void (*AddCertCb)(CertificateManagerData *cfm, ECert *cert);
|
||||
|
||||
static void
|
||||
add_user_cert (CertificateManagerData *cfm, ECert *cert)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreeIter *parent_iter = NULL;
|
||||
const char *organization = e_cert_get_org (cert);
|
||||
const char *common_name;
|
||||
|
||||
if (organization) {
|
||||
parent_iter = g_hash_table_lookup (cfm->yourcerts_root_hash, organization);
|
||||
@ -229,14 +385,16 @@ add_user_cert (CertificateManagerData *cfm, ECert *cert)
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (cfm->yourcerts_treemodel), &iter, parent_iter);
|
||||
|
||||
common_name = e_cert_get_cn (cert);
|
||||
if (common_name) {
|
||||
if (e_cert_get_cn (cert))
|
||||
gtk_tree_store_set (GTK_TREE_STORE (cfm->yourcerts_treemodel), &iter,
|
||||
0, common_name, -1);
|
||||
}
|
||||
0, e_cert_get_cn (cert),
|
||||
4, cert,
|
||||
-1);
|
||||
else
|
||||
gtk_tree_store_set (GTK_TREE_STORE (cfm->yourcerts_treemodel), &iter,
|
||||
0, e_cert_get_nickname (cert), -1);
|
||||
0, e_cert_get_nickname (cert),
|
||||
4, cert,
|
||||
-1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -251,7 +409,6 @@ add_ca_cert (CertificateManagerData *cfm, ECert *cert)
|
||||
GtkTreeIter iter;
|
||||
GtkTreeIter *parent_iter = NULL;
|
||||
const char *organization = e_cert_get_org (cert);
|
||||
const char *common_name;
|
||||
|
||||
if (organization) {
|
||||
parent_iter = g_hash_table_lookup (cfm->authoritycerts_root_hash, organization);
|
||||
@ -272,19 +429,60 @@ add_ca_cert (CertificateManagerData *cfm, ECert *cert)
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (cfm->authoritycerts_treemodel), &iter, parent_iter);
|
||||
|
||||
common_name = e_cert_get_cn (cert);
|
||||
if (common_name) {
|
||||
if (e_cert_get_cn (cert))
|
||||
gtk_tree_store_set (GTK_TREE_STORE (cfm->authoritycerts_treemodel), &iter,
|
||||
0, common_name, -1);
|
||||
}
|
||||
0, e_cert_get_cn (cert),
|
||||
1, cert,
|
||||
-1);
|
||||
else
|
||||
gtk_tree_store_set (GTK_TREE_STORE (cfm->authoritycerts_treemodel), &iter,
|
||||
0, e_cert_get_nickname (cert), -1);
|
||||
0, e_cert_get_nickname (cert),
|
||||
1, cert,
|
||||
-1);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_key (gpointer data)
|
||||
{
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_value (gpointer data)
|
||||
{
|
||||
gtk_tree_iter_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
unload_certs (CertificateManagerData *cfm,
|
||||
ECertType type)
|
||||
{
|
||||
switch (type) {
|
||||
case E_CERT_USER:
|
||||
break;
|
||||
case E_CERT_CONTACT:
|
||||
break;
|
||||
case E_CERT_SITE:
|
||||
break;
|
||||
case E_CERT_CA:
|
||||
cfm->authoritycerts_treemodel = create_authoritycerts_treemodel ();
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (cfm->authoritycerts_treeview),
|
||||
GTK_TREE_MODEL (cfm->authoritycerts_treemodel));
|
||||
|
||||
if (cfm->authoritycerts_root_hash)
|
||||
g_hash_table_destroy (cfm->authoritycerts_root_hash);
|
||||
|
||||
cfm->authoritycerts_root_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
destroy_key, destroy_value);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
load_certs (CertificateManagerData *cfm,
|
||||
CertType type,
|
||||
ECertType type,
|
||||
AddCertCb add_cert)
|
||||
{
|
||||
CERTCertList *certList;
|
||||
@ -298,11 +496,10 @@ load_certs (CertificateManagerData *cfm,
|
||||
!CERT_LIST_END(node, certList);
|
||||
node = CERT_LIST_NEXT(node)) {
|
||||
ECert *cert = e_cert_new ((CERTCertificate*)node->cert);
|
||||
if (get_cert_type(cert) == type) {
|
||||
if (e_cert_get_cert_type(cert) == type) {
|
||||
printf ("cert (nickname = '%s') matches\n", e_cert_get_nickname (cert));
|
||||
add_cert (cfm, cert);
|
||||
}
|
||||
/* XXX we leak cert */
|
||||
}
|
||||
|
||||
}
|
||||
@ -310,9 +507,14 @@ load_certs (CertificateManagerData *cfm,
|
||||
static void
|
||||
populate_ui (CertificateManagerData *cfm)
|
||||
{
|
||||
load_certs (cfm, USER_CERT, add_user_cert);
|
||||
load_certs (cfm, CONTACT_CERT, add_contact_cert);
|
||||
load_certs (cfm, CA_CERT, add_ca_cert);
|
||||
unload_certs (cfm, E_CERT_USER);
|
||||
load_certs (cfm, E_CERT_USER, add_user_cert);
|
||||
|
||||
unload_certs (cfm, E_CERT_CONTACT);
|
||||
load_certs (cfm, E_CERT_CONTACT, add_contact_cert);
|
||||
|
||||
unload_certs (cfm, E_CERT_CA);
|
||||
load_certs (cfm, E_CERT_CA, add_ca_cert);
|
||||
}
|
||||
|
||||
EvolutionConfigControl*
|
||||
@ -321,10 +523,8 @@ certificate_manager_config_control_new (void)
|
||||
CertificateManagerData *cfm_data;
|
||||
GtkWidget *control_widget;
|
||||
|
||||
/* XXX this should happen someplace else, and shouldn't
|
||||
reference my default mozilla profile :) */
|
||||
if (SECSuccess != NSS_InitReadWrite ("/home/toshok/.mozilla/default/xuvq7jx3.slt"))
|
||||
return NULL;
|
||||
/* We need to peek the db here to make sure it (and NSS) are fully initialized. */
|
||||
e_cert_db_peek ();
|
||||
|
||||
cfm_data = g_new0 (CertificateManagerData, 1);
|
||||
cfm_data->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, NULL, NULL);
|
||||
@ -333,6 +533,17 @@ certificate_manager_config_control_new (void)
|
||||
cfm_data->contactcerts_treeview = glade_xml_get_widget (cfm_data->gui, "contactcerts-treeview");
|
||||
cfm_data->authoritycerts_treeview = glade_xml_get_widget (cfm_data->gui, "authoritycerts-treeview");
|
||||
|
||||
cfm_data->view_your_button = glade_xml_get_widget (cfm_data->gui, "your-view-button");
|
||||
cfm_data->backup_your_button = glade_xml_get_widget (cfm_data->gui, "your-backup-button");
|
||||
cfm_data->backup_all_your_button = glade_xml_get_widget (cfm_data->gui, "your-backup-all-button");
|
||||
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_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");
|
||||
cfm_data->delete_ca_button = glade_xml_get_widget (cfm_data->gui, "authority-delete-button");
|
||||
|
||||
initialize_yourcerts_ui(cfm_data);
|
||||
initialize_contactcerts_ui(cfm_data);
|
||||
initialize_authoritycerts_ui(cfm_data);
|
||||
|
@ -1173,6 +1173,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="your-view-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">View</property>
|
||||
@ -1184,6 +1185,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="your-backup-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
@ -1325,6 +1327,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="your-delete-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-delete</property>
|
||||
@ -1429,6 +1432,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="contact-view-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">View</property>
|
||||
@ -1440,6 +1444,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="contact-edit-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
@ -1516,6 +1521,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="contact-delete-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-delete</property>
|
||||
@ -1620,6 +1626,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="authority-view-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">View</property>
|
||||
@ -1631,6 +1638,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="authority-edit-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
@ -1707,6 +1715,7 @@
|
||||
<child>
|
||||
<widget class="GtkButton" id="authority-delete-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-delete</property>
|
||||
@ -1750,4 +1759,214 @@
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkDialog" id="dialog1">
|
||||
<property name="title" translatable="yes">dialog1</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="has_separator">True</property>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area2">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancelbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="response_id">-6</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="okbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="response_id">-5</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label64">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">You have been asked to trust a new Certificate Authority (CA).</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label65">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Do you want to trust "%s" for the following purposes?</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox7">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="checkbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Trust this CA to identify web sites.</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="checkbutton2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Trust this CA to identify email users.</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="checkbutton3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Trust this CA to identify software developers.</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label66">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Before trusting this CA for any purpose, you should examine its certificate and its policy and procedures (if available).</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment5">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">1</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="button1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">View Certificate</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
||||
|
@ -15,10 +15,12 @@ INCLUDES = \
|
||||
-DLIBGNOME_DISABLE_DEPRECATED \
|
||||
-DLIBGNOMEUI_DISABLE_DEPRECATED \
|
||||
$(EVOLUTION_ADDRESSBOOK_CFLAGS) \
|
||||
$(CAMEL_CFLAGS)
|
||||
$(CERT_UI_CFLAGS)
|
||||
|
||||
noinst_LTLIBRARIES = libessmime.la
|
||||
|
||||
libessmime_la_SOURCES = \
|
||||
e-cert.c \
|
||||
e-cert.h
|
||||
e-cert.h \
|
||||
e-cert-db.c \
|
||||
e-cert-db.h
|
||||
|
822
smime/lib/e-cert-db.c
Normal file
822
smime/lib/e-cert-db.c
Normal file
@ -0,0 +1,822 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/* e-cert-db.c
|
||||
*
|
||||
* Copyright (C) 2003 Ximian, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Chris Toshok (toshok@ximian.com)
|
||||
*/
|
||||
|
||||
/* The following is the mozilla license blurb, as the bodies of most
|
||||
of these functions were derived from the mozilla source. */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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-db.h"
|
||||
|
||||
#include "nss.h"
|
||||
#include "pk11func.h"
|
||||
#include "certdb.h"
|
||||
#include <e-util/e-dialog-utils.h>
|
||||
#include <gtk/gtkmessagedialog.h>
|
||||
#include <libgnome/gnome-i18n.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct _ECertDBPrivate {
|
||||
};
|
||||
|
||||
#define PARENT_TYPE G_TYPE_OBJECT
|
||||
static GObjectClass *parent_class;
|
||||
|
||||
static CERTDERCerts* e_cert_db_get_certs_from_package (PRArenaPool *arena, char *data, guint32 length);
|
||||
|
||||
|
||||
|
||||
static void
|
||||
e_cert_db_dispose (GObject *object)
|
||||
{
|
||||
ECertDB *ec = E_CERT_DB (object);
|
||||
|
||||
if (!ec->priv)
|
||||
return;
|
||||
|
||||
/* XXX free instance specific data */
|
||||
|
||||
g_free (ec->priv);
|
||||
ec->priv = NULL;
|
||||
|
||||
if (G_OBJECT_CLASS (parent_class)->dispose)
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
e_cert_db_class_init (ECertDBClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
char *evolution_dir_path;
|
||||
gboolean success;
|
||||
|
||||
object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
parent_class = g_type_class_ref (PARENT_TYPE);
|
||||
|
||||
object_class->dispose = e_cert_db_dispose;
|
||||
|
||||
evolution_dir_path = g_build_path ("/", g_get_home_dir (), ".evolution", NULL);
|
||||
|
||||
/* we initialize NSS here to make sure it only happens once */
|
||||
success = (SECSuccess == NSS_InitReadWrite (evolution_dir_path));
|
||||
if (!success) {
|
||||
success = (SECSuccess == NSS_Init (evolution_dir_path));
|
||||
if (success)
|
||||
g_warning ("opening cert databases read-only");
|
||||
}
|
||||
if (!success) {
|
||||
success = (SECSuccess == NSS_NoDB_Init (evolution_dir_path));
|
||||
if (success)
|
||||
g_warning ("initializing security library without cert databases.");
|
||||
}
|
||||
g_free (evolution_dir_path);
|
||||
|
||||
if (!success) {
|
||||
g_warning ("Failed all methods for initializing NSS");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
e_cert_db_init (ECertDB *ec)
|
||||
{
|
||||
ec->priv = g_new0 (ECertDBPrivate, 1);
|
||||
}
|
||||
|
||||
GType
|
||||
e_cert_db_get_type (void)
|
||||
{
|
||||
static GType cert_type = 0;
|
||||
|
||||
if (!cert_type) {
|
||||
static const GTypeInfo cert_info = {
|
||||
sizeof (ECertDBClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) e_cert_db_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (ECertDB),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) e_cert_db_init,
|
||||
};
|
||||
|
||||
cert_type = g_type_register_static (PARENT_TYPE, "ECertDB", &cert_info, 0);
|
||||
}
|
||||
|
||||
return cert_type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;
|
||||
static ECertDB *cert_db = NULL;
|
||||
|
||||
ECertDB*
|
||||
e_cert_db_peek (void)
|
||||
{
|
||||
g_static_mutex_lock (&init_mutex);
|
||||
if (!cert_db)
|
||||
cert_db = g_object_new (E_TYPE_CERT_DB, NULL);
|
||||
g_static_mutex_unlock (&init_mutex);
|
||||
|
||||
return cert_db;
|
||||
}
|
||||
|
||||
void
|
||||
e_cert_db_shutdown (void)
|
||||
{
|
||||
/* XXX */
|
||||
}
|
||||
|
||||
/* searching for certificates */
|
||||
ECert*
|
||||
e_cert_db_find_cert_by_nickname (ECertDB *certdb,
|
||||
const char *nickname,
|
||||
GError **error)
|
||||
{
|
||||
// nsNSSShutDownPreventionLock locker;
|
||||
CERTCertificate *cert = NULL;
|
||||
|
||||
//PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting \"%s\"\n", asciiname));
|
||||
#if 0
|
||||
// what it should be, but for now...
|
||||
if (aToken) {
|
||||
cert = PK11_FindCertFromNickname(asciiname, NULL);
|
||||
} else {
|
||||
cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), asciiname);
|
||||
}
|
||||
#endif
|
||||
cert = PK11_FindCertFromNickname((char*)nickname, NULL);
|
||||
if (!cert) {
|
||||
cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), (char*)nickname);
|
||||
}
|
||||
|
||||
|
||||
if (cert) {
|
||||
// PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("got it\n"));
|
||||
ECert *ecert = e_cert_new (cert);
|
||||
return ecert;
|
||||
}
|
||||
else {
|
||||
/* XXX gerror */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ECert*
|
||||
e_cert_db_find_cert_by_key (ECertDB *certdb,
|
||||
const char *db_key,
|
||||
GError **error)
|
||||
{
|
||||
#if 0
|
||||
// nsNSSShutDownPreventionLock locker;
|
||||
SECItem keyItem = {siBuffer, NULL, 0};
|
||||
SECItem *dummy;
|
||||
CERTIssuerAndSN issuerSN;
|
||||
unsigned long moduleID,slotID;
|
||||
CERTCertificate *cert;
|
||||
|
||||
if (!db_key) {
|
||||
/* XXX gerror */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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
|
||||
moduleID = NS_NSS_GET_LONG(keyItem.data);
|
||||
slotID = NS_NSS_GET_LONG(&keyItem.data[NS_NSS_LONG]);
|
||||
|
||||
// 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];
|
||||
issuerSN.derIssuer.data= &keyItem.data[NS_NSS_LONG*4+
|
||||
issuerSN.serialNumber.len];
|
||||
|
||||
cert = CERT_FindCertByIssuerAndSN(CERT_GetDefaultCertDB(), &issuerSN);
|
||||
PR_FREEIF(keyItem.data);
|
||||
if (cert) {
|
||||
ECert *ecert = e_cert_new (cert);
|
||||
return e_cert;
|
||||
}
|
||||
|
||||
/* XXX gerror */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
GList*
|
||||
e_cert_db_get_cert_nicknames (ECertDB *certdb,
|
||||
ECertType cert_type,
|
||||
GError **error)
|
||||
{
|
||||
}
|
||||
|
||||
ECert*
|
||||
e_cert_db_find_email_encryption_cert (ECertDB *certdb,
|
||||
const char *nickname,
|
||||
GError **error)
|
||||
{
|
||||
}
|
||||
|
||||
ECert*
|
||||
e_cert_db_find_email_signing_cert (ECertDB *certdb,
|
||||
const char *nickname,
|
||||
GError **error)
|
||||
{
|
||||
}
|
||||
|
||||
ECert*
|
||||
e_cert_db_find_cert_by_email_address (ECertDB *certdb,
|
||||
const char *email,
|
||||
GError **error)
|
||||
{
|
||||
/* nsNSSShutDownPreventionLock locker; */
|
||||
ECert *cert;
|
||||
CERTCertificate *any_cert = CERT_FindCertByNicknameOrEmailAddr(CERT_GetDefaultCertDB(),
|
||||
(char*)email);
|
||||
CERTCertList *certlist;
|
||||
|
||||
if (!any_cert) {
|
||||
/* XXX gerror */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* any_cert now contains a cert with the right subject, but it might not have the correct usage */
|
||||
certlist = CERT_CreateSubjectCertList(NULL,
|
||||
CERT_GetDefaultCertDB(),
|
||||
&any_cert->derSubject,
|
||||
PR_Now(), PR_TRUE);
|
||||
if (!certlist) {
|
||||
/* XXX gerror */
|
||||
/* XXX free any_cert */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (SECSuccess != CERT_FilterCertListByUsage(certlist, certUsageEmailRecipient, PR_FALSE)) {
|
||||
/* XXX gerror */
|
||||
/* XXX free any_cert */
|
||||
/* XXX free certlist */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) {
|
||||
/* XXX gerror */
|
||||
/* XXX free any_cert */
|
||||
/* XXX free certlist */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cert = e_cert_new (CERT_LIST_HEAD(certlist)->cert);
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_confirm_download_ca_cert (ECert *cert, guint32 *trustBits, gboolean *allow)
|
||||
{
|
||||
/* right now just allow it and set the trustBits to 0 */
|
||||
*trustBits = 0;
|
||||
*allow = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_ca_cert_download(GList *certs, GError **error)
|
||||
{
|
||||
ECert *certToShow;
|
||||
SECItem der;
|
||||
CERTCertificate *tmpCert;
|
||||
|
||||
/* First thing we have to do is figure out which certificate
|
||||
we're gonna present to the user. The CA may have sent down
|
||||
a list of certs which may or may not be a chained list of
|
||||
certs. Until the day we can design some solid UI for the
|
||||
general case, we'll code to the > 90% case. That case is
|
||||
where a CA sends down a list that is a chain up to its root
|
||||
in either ascending or descending order. What we're gonna
|
||||
do is compare the first 2 entries, if the first was signed
|
||||
by the second, we assume the leaf cert is the first cert
|
||||
and display it. If the second cert was signed by the first
|
||||
cert, then we assume the first cert is the root and the
|
||||
last cert in the array is the leaf. In this case we
|
||||
display the last cert.
|
||||
*/
|
||||
|
||||
/* nsNSSShutDownPreventionLock locker;*/
|
||||
|
||||
if (certs == NULL) {
|
||||
g_warning ("Didn't get any certs to import.");
|
||||
return TRUE;
|
||||
}
|
||||
else if (certs->next == NULL) {
|
||||
/* there's 1 cert */
|
||||
certToShow = E_CERT (certs->data);
|
||||
}
|
||||
else {
|
||||
/* there are multiple certs */
|
||||
ECert *cert0;
|
||||
ECert *cert1;
|
||||
const char* cert0SubjectName;
|
||||
const char* cert0IssuerName;
|
||||
const char* cert1SubjectName;
|
||||
const char* cert1IssuerName;
|
||||
|
||||
cert0 = E_CERT (certs->data);
|
||||
cert1 = E_CERT (certs->next->data);
|
||||
|
||||
cert0IssuerName = e_cert_get_issuer_name (cert0);
|
||||
cert0SubjectName = e_cert_get_subject_name (cert0);
|
||||
|
||||
cert1IssuerName = e_cert_get_issuer_name (cert1);
|
||||
cert1SubjectName = e_cert_get_subject_name (cert1);
|
||||
|
||||
if (!strcmp(cert1IssuerName, cert0SubjectName)) {
|
||||
/* In this case, the first cert in the list signed the second,
|
||||
so the first cert is the root. Let's display the last cert
|
||||
in the list. */
|
||||
certToShow = E_CERT (g_list_last (certs)->data);
|
||||
}
|
||||
else if (!strcmp(cert0IssuerName, cert1SubjectName)) {
|
||||
/* In this case the second cert has signed the first cert. The
|
||||
first cert is the leaf, so let's display it. */
|
||||
certToShow = cert0;
|
||||
} else {
|
||||
/* It's not a chain, so let's just show the first one in the
|
||||
downloaded list. */
|
||||
certToShow = cert0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!certToShow) {
|
||||
/* XXX gerror */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!e_cert_get_raw_der (certToShow, (char**)&der.data, &der.len)) {
|
||||
/* XXX gerror */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
/*PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Creating temp cert\n"));*/
|
||||
CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
|
||||
tmpCert = CERT_FindCertByDERCert(certdb, &der);
|
||||
if (!tmpCert) {
|
||||
tmpCert = CERT_NewTempCertificate(certdb, &der,
|
||||
NULL, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
if (!tmpCert) {
|
||||
g_warning ("Couldn't create cert from DER blob");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
CERTCertificateCleaner tmpCertCleaner(tmpCert);
|
||||
#endif
|
||||
|
||||
if (tmpCert->isperm) {
|
||||
e_notice (NULL, GTK_MESSAGE_WARNING, _("Certificate already exists"));
|
||||
/* XXX gerror */
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
guint32 trustBits;
|
||||
gboolean allow;
|
||||
char *nickname;
|
||||
SECStatus srv;
|
||||
|
||||
if (!_confirm_download_ca_cert (certToShow, &trustBits, &allow)) {
|
||||
/* XXX gerror */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!allow) {
|
||||
/* XXX gerror */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//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);
|
||||
#endif
|
||||
|
||||
srv = CERT_AddTempCertToPerm(tmpCert,
|
||||
nickname,
|
||||
/*XXX trust.GetTrust()*/ 0);
|
||||
|
||||
if (srv != SECSuccess) {
|
||||
/* XXX gerror */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* 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);
|
||||
for (PRUint32 i=0; i<numCerts; i++) {
|
||||
if (i == selCertIndex)
|
||||
continue;
|
||||
|
||||
certToShow = do_QueryElementAt(x509Certs, i);
|
||||
certToShow->GetRawDER(&der.len, (PRUint8 **)&der.data);
|
||||
|
||||
CERTCertificate *tmpCert2 =
|
||||
CERT_NewTempCertificate(certdb, &der, nsnull, PR_FALSE, PR_TRUE);
|
||||
|
||||
if (!tmpCert2) {
|
||||
NS_ASSERTION(0, "Couldn't create temp cert from DER blob\n");
|
||||
continue; // Let's try to import the rest of 'em
|
||||
}
|
||||
nickname.Adopt(CERT_MakeCANickname(tmpCert2));
|
||||
CERT_AddTempCertToPerm(tmpCert2, NS_CONST_CAST(char*,nickname.get()),
|
||||
defaultTrust.GetTrust());
|
||||
CERT_DestroyCertificate(tmpCert2);
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* deleting certificates */
|
||||
gboolean
|
||||
e_cert_db_delete_cert (ECertDB *certdb,
|
||||
ECert *ecert)
|
||||
{
|
||||
// nsNSSShutDownPreventionLock locker;
|
||||
// nsNSSCertificate *nssCert = NS_STATIC_CAST(nsNSSCertificate*, aCert);
|
||||
|
||||
CERTCertificate *cert;
|
||||
SECStatus srv = SECSuccess;
|
||||
if (!e_cert_mark_for_deletion (ecert)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cert = e_cert_get_internal_cert (ecert);
|
||||
if (cert->slot && e_cert_get_cert_type (ecert) != E_CERT_USER) {
|
||||
/* To delete a cert of a slot (builtin, most likely), mark it as
|
||||
completely untrusted. This way we keep a copy cached in the
|
||||
local database, and next time we try to load it off of the
|
||||
external token/slot, we'll know not to trust it. We don't
|
||||
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);
|
||||
srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(),
|
||||
cert, trust.GetTrust());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("cert deleted: %d", srv));
|
||||
#endif
|
||||
return (srv) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
/* importing certificates */
|
||||
gboolean
|
||||
e_cert_db_import_certs (ECertDB *certdb,
|
||||
char *data, guint32 length,
|
||||
ECertType cert_type,
|
||||
GError **error)
|
||||
{
|
||||
/*nsNSSShutDownPreventionLock locker;*/
|
||||
PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
GList *certs = NULL;
|
||||
CERTDERCerts *certCollection = e_cert_db_get_certs_from_package (arena, data, length);
|
||||
int i;
|
||||
gboolean rv;
|
||||
|
||||
if (!certCollection) {
|
||||
/* XXX gerror */
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now let's create some certs to work with */
|
||||
for (i=0; i<certCollection->numcerts; i++) {
|
||||
SECItem *currItem = &certCollection->rawCerts[i];
|
||||
ECert *cert;
|
||||
|
||||
cert = e_cert_new_from_der ((char*)currItem->data, currItem->len);
|
||||
if (!cert) {
|
||||
/* XXX gerror */
|
||||
g_list_foreach (certs, (GFunc)g_object_unref, NULL);
|
||||
g_list_free (certs);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
certs = g_list_append (certs, cert);
|
||||
}
|
||||
switch (cert_type) {
|
||||
case E_CERT_CA:
|
||||
rv = handle_ca_cert_download(certs, error);
|
||||
break;
|
||||
default:
|
||||
// We only deal with import CA certs in this method currently.
|
||||
/* XXX gerror */
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
rv = FALSE;
|
||||
}
|
||||
|
||||
g_list_foreach (certs, (GFunc)g_object_unref, NULL);
|
||||
g_list_free (certs);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_cert_db_import_email_cert (ECertDB *certdb,
|
||||
char *data, guint32 length,
|
||||
GError **error)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), collectArgs->rawCerts,
|
||||
(char *)NULL, PR_FALSE, PR_TRUE);
|
||||
if (!cert) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
slot = PK11_KeyForCertExists(cert, NULL, NULL);
|
||||
if ( slot == NULL ) {
|
||||
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;
|
||||
}
|
||||
else {
|
||||
g_assert_not_reached ();
|
||||
/* nickname = default_nickname(cert, NULL); */
|
||||
}
|
||||
|
||||
/* user wants to import the cert */
|
||||
slot = PK11_ImportCertForKey(cert, nickname, NULL);
|
||||
if (!slot) {
|
||||
goto loser;
|
||||
}
|
||||
PK11_FreeSlot(slot);
|
||||
numCACerts = collectArgs->numcerts - 1;
|
||||
|
||||
if (numCACerts) {
|
||||
CACerts = collectArgs->rawCerts+1;
|
||||
if ( ! CERT_ImportCAChain(CACerts, numCACerts, certUsageUserCertImport) ) {
|
||||
rv = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
loser:
|
||||
if ( cert ) {
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_cert_db_import_server_cert (ECertDB *certdb,
|
||||
char *data, guint32 length,
|
||||
GError **error)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_cert_db_import_certs_from_file (ECertDB *cert_db,
|
||||
const char *file_path,
|
||||
ECertType cert_type,
|
||||
GError **error)
|
||||
{
|
||||
gboolean rv;
|
||||
int fd;
|
||||
struct stat sb;
|
||||
char *buf;
|
||||
int bytes_read;
|
||||
|
||||
switch (cert_type) {
|
||||
case E_CERT_CA:
|
||||
case E_CERT_CONTACT:
|
||||
case E_CERT_SITE:
|
||||
/* good */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* not supported (yet) */
|
||||
/* XXX gerror */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fd = open (file_path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
/* XXX gerror */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (-1 == fstat (fd, &sb)) {
|
||||
/* XXX gerror */
|
||||
close (fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
buf = g_malloc (sb.st_size);
|
||||
if (!buf) {
|
||||
/* XXX gerror */
|
||||
close (fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bytes_read = read (fd, buf, sb.st_size);
|
||||
|
||||
close (fd);
|
||||
|
||||
if (bytes_read != sb.st_size) {
|
||||
/* XXX gerror */
|
||||
rv = FALSE;
|
||||
}
|
||||
else {
|
||||
printf ("importing %d bytes from `%s'\n", bytes_read, file_path);
|
||||
|
||||
switch (cert_type) {
|
||||
case E_CERT_CA:
|
||||
rv = e_cert_db_import_certs (cert_db, buf, bytes_read, cert_type, error);
|
||||
break;
|
||||
|
||||
case E_CERT_SITE:
|
||||
rv = e_cert_db_import_server_cert (cert_db, buf, bytes_read, error);
|
||||
break;
|
||||
|
||||
case E_CERT_CONTACT:
|
||||
rv = e_cert_db_import_email_cert (cert_db, buf, bytes_read, error);
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_cert_db_import_pkcs12_file (ECertDB *cert_db,
|
||||
const char *file_path,
|
||||
GError **error)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_cert_db_export_pkcs12_file (ECertDB *cert_db,
|
||||
const char *file_path,
|
||||
GList *certs,
|
||||
GError **error)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
static SECStatus PR_CALLBACK
|
||||
collect_certs(void *arg, SECItem **certs, int numcerts)
|
||||
{
|
||||
CERTDERCerts *collectArgs;
|
||||
SECItem *cert;
|
||||
SECStatus rv;
|
||||
|
||||
collectArgs = (CERTDERCerts *)arg;
|
||||
|
||||
collectArgs->numcerts = numcerts;
|
||||
collectArgs->rawCerts = (SECItem *) PORT_ArenaZAlloc(collectArgs->arena, sizeof(SECItem) * numcerts);
|
||||
if ( collectArgs->rawCerts == NULL )
|
||||
return(SECFailure);
|
||||
|
||||
cert = collectArgs->rawCerts;
|
||||
|
||||
while ( numcerts-- ) {
|
||||
rv = SECITEM_CopyItem(collectArgs->arena, cert, *certs);
|
||||
if ( rv == SECFailure )
|
||||
return(SECFailure);
|
||||
cert++;
|
||||
certs++;
|
||||
}
|
||||
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
static CERTDERCerts*
|
||||
e_cert_db_get_certs_from_package (PRArenaPool *arena,
|
||||
char *data,
|
||||
guint32 length)
|
||||
{
|
||||
/*nsNSSShutDownPreventionLock locker;*/
|
||||
CERTDERCerts *collectArgs =
|
||||
(CERTDERCerts *)PORT_ArenaZAlloc(arena, sizeof(CERTDERCerts));
|
||||
SECStatus sec_rv;
|
||||
|
||||
if (!collectArgs)
|
||||
return NULL;
|
||||
|
||||
collectArgs->arena = arena;
|
||||
sec_rv = CERT_DecodeCertPackage(data,
|
||||
length, collect_certs,
|
||||
(void *)collectArgs);
|
||||
|
||||
if (sec_rv != SECSuccess)
|
||||
return NULL;
|
||||
|
||||
return collectArgs;
|
||||
}
|
128
smime/lib/e-cert-db.h
Normal file
128
smime/lib/e-cert-db.h
Normal file
@ -0,0 +1,128 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* Authors: Chris Toshok <toshok@ximian.com>
|
||||
*
|
||||
* Copyright (C) 2003 Ximian, Inc. (www.ximian.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_DB_H_
|
||||
#define _E_CERT_DB_H_
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "e-cert.h"
|
||||
#include <cert.h>
|
||||
|
||||
#define E_TYPE_CERT_DB (e_cert_db_get_type ())
|
||||
#define E_CERT_DB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CERT_DB, ECertDB))
|
||||
#define E_CERT_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CERT_DB, ECertDBClass))
|
||||
#define E_IS_CERT_DB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CERT_DB))
|
||||
#define E_IS_CERT_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CERT_DB))
|
||||
#define E_CERT_DB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CERT_DB, ECertDBClass))
|
||||
|
||||
typedef struct _ECertDB ECertDB;
|
||||
typedef struct _ECertDBClass ECertDBClass;
|
||||
typedef struct _ECertDBPrivate ECertDBPrivate;
|
||||
|
||||
struct _ECertDB {
|
||||
GObject parent;
|
||||
|
||||
ECertDBPrivate *priv;
|
||||
};
|
||||
|
||||
struct _ECertDBClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_ecert_reserved0) (void);
|
||||
void (*_ecert_reserved1) (void);
|
||||
void (*_ecert_reserved2) (void);
|
||||
void (*_ecert_reserved3) (void);
|
||||
void (*_ecert_reserved4) (void);
|
||||
};
|
||||
|
||||
GType e_cert_db_get_type (void);
|
||||
|
||||
/* single instance */
|
||||
ECertDB* e_cert_db_peek (void);
|
||||
|
||||
void e_cert_db_shutdown (void);
|
||||
|
||||
/* searching for certificates */
|
||||
ECert* e_cert_db_find_cert_by_nickname (ECertDB *certdb,
|
||||
const char *nickname,
|
||||
GError **error);
|
||||
|
||||
ECert* e_cert_db_find_cert_by_key (ECertDB *certdb,
|
||||
const char *db_key,
|
||||
GError **error);
|
||||
|
||||
GList* e_cert_db_get_cert_nicknames (ECertDB *certdb,
|
||||
ECertType cert_type,
|
||||
GError **error);
|
||||
|
||||
|
||||
ECert* e_cert_db_find_email_encryption_cert (ECertDB *certdb,
|
||||
const char *nickname,
|
||||
GError **error);
|
||||
|
||||
ECert* e_cert_db_find_email_signing_cert (ECertDB *certdb,
|
||||
const char *nickname,
|
||||
GError **error);
|
||||
|
||||
ECert* e_cert_db_find_cert_by_email_address (ECertDB *certdb,
|
||||
const char *nickname,
|
||||
GError **error);
|
||||
|
||||
/* deleting certificates */
|
||||
gboolean e_cert_db_delete_cert (ECertDB *certdb,
|
||||
ECert *cert);
|
||||
|
||||
/* importing certificates */
|
||||
gboolean e_cert_db_import_certs (ECertDB *certdb,
|
||||
char *data, guint32 length,
|
||||
ECertType cert_type,
|
||||
GError **error);
|
||||
|
||||
gboolean e_cert_db_import_email_cert (ECertDB *certdb,
|
||||
char *data, guint32 length,
|
||||
GError **error);
|
||||
|
||||
gboolean e_cert_db_import_user_cert (ECertDB *certdb,
|
||||
char *data, guint32 length,
|
||||
GError **error);
|
||||
|
||||
gboolean e_cert_db_import_server_cert (ECertDB *certdb,
|
||||
char *data, guint32 length,
|
||||
GError **error);
|
||||
|
||||
gboolean e_cert_db_import_certs_from_file (ECertDB *cert_db,
|
||||
const char *file_path,
|
||||
ECertType cert_type,
|
||||
GError **error);
|
||||
|
||||
gboolean e_cert_db_import_pkcs12_file (ECertDB *cert_db,
|
||||
const char *file_path,
|
||||
GError **error);
|
||||
|
||||
gboolean e_cert_db_export_pkcs12_file (ECertDB *cert_db,
|
||||
const char *file_path,
|
||||
GList *certs,
|
||||
GError **error);
|
||||
|
||||
|
||||
#endif /* _E_CERT_DB_H_ */
|
@ -20,12 +20,54 @@
|
||||
* Author: Chris Toshok (toshok@ximian.com)
|
||||
*/
|
||||
|
||||
/* The following is the mozilla license blurb, as the bodies some of
|
||||
these functions were derived from the mozilla source. */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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.h"
|
||||
#include "pk11func.h"
|
||||
#include "certdb.h"
|
||||
|
||||
struct _ECertPrivate {
|
||||
CERTCertificate *cert;
|
||||
|
||||
/* pointers we cache since the nss implementation allocs the
|
||||
string */
|
||||
char *org_name;
|
||||
char *cn;
|
||||
|
||||
gboolean delete;
|
||||
};
|
||||
|
||||
#define PARENT_TYPE G_TYPE_OBJECT
|
||||
@ -42,11 +84,23 @@ e_cert_dispose (GObject *object)
|
||||
if (ec->priv->org_name)
|
||||
PORT_Free (ec->priv->org_name);
|
||||
if (ec->priv->cn)
|
||||
PORT_Free (ec->priv->org_name);
|
||||
PORT_Free (ec->priv->cn);
|
||||
|
||||
if (ec->priv->delete) {
|
||||
printf ("attempting to delete cert marked for deletion\n");
|
||||
if (e_cert_get_cert_type (ec) == E_CERT_USER) {
|
||||
PK11_DeleteTokenCertAndKey(ec->priv->cert, NULL);
|
||||
} else if (!PK11_IsReadOnly(ec->priv->cert->slot)) {
|
||||
/* If the list of built-ins does contain a non-removable
|
||||
copy of this certificate, our call will not remove
|
||||
the certificate permanently, but rather remove all trust. */
|
||||
SEC_DeletePermCertificate(ec->priv->cert);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (ec->priv);
|
||||
ec->priv = NULL;
|
||||
|
||||
|
||||
if (G_OBJECT_CLASS (parent_class)->dispose)
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
@ -115,9 +169,47 @@ e_cert_new (CERTCertificate *cert)
|
||||
return ecert;
|
||||
}
|
||||
|
||||
ECert*
|
||||
e_cert_new_from_der (char *data, guint32 len)
|
||||
{
|
||||
CERTCertificate *cert = CERT_DecodeCertFromPackage (data, len);
|
||||
|
||||
if (!cert)
|
||||
return NULL;
|
||||
|
||||
if (cert->dbhandle == NULL)
|
||||
cert->dbhandle = CERT_GetDefaultCertDB();
|
||||
|
||||
return e_cert_new (cert);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
CERTCertificate*
|
||||
e_cert_get_internal_cert (ECert *cert)
|
||||
{
|
||||
/* XXX should this refcnt it? */
|
||||
return cert->priv->cert;
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_cert_get_raw_der (ECert *cert, char **data, guint32 *len)
|
||||
{
|
||||
/* XXX do we really need to check if cert->priv->cert is NULL
|
||||
here? it should always be non-null if we have the
|
||||
ECert.. */
|
||||
if (cert->priv->cert) {
|
||||
*data = (char*)cert->priv->cert->derCert.data;
|
||||
*len = (guint32)cert->priv->cert->derCert.len;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*len = 0;
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
const char*
|
||||
e_cert_get_nickname (ECert *cert)
|
||||
{
|
||||
@ -141,8 +233,46 @@ e_cert_get_cn (ECert *cert)
|
||||
return cert->priv->cn;
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_cert_is_ca_cert (ECert *cert)
|
||||
const char*
|
||||
e_cert_get_issuer_name (ECert *cert)
|
||||
{
|
||||
return CERT_IsCACert (cert->priv->cert, NULL);
|
||||
return cert->priv->cert->issuerName;
|
||||
}
|
||||
|
||||
const char*
|
||||
e_cert_get_subject_name (ECert *cert)
|
||||
{
|
||||
return cert->priv->cert->subjectName;
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_cert_mark_for_deletion (ECert *cert)
|
||||
{
|
||||
// nsNSSShutDownPreventionLock locker;
|
||||
|
||||
#if 0
|
||||
// make sure user is logged in to the token
|
||||
nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
|
||||
#endif
|
||||
|
||||
if (PK11_NeedLogin(cert->priv->cert->slot)
|
||||
&& !PK11_NeedUserInit(cert->priv->cert->slot)
|
||||
&& !PK11_IsInternal(cert->priv->cert->slot)) {
|
||||
if (SECSuccess != PK11_Authenticate(cert->priv->cert->slot, PR_TRUE, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
cert->priv->delete = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ECertType
|
||||
e_cert_get_cert_type (ECert *cert)
|
||||
{
|
||||
if (CERT_IsCACert (cert->priv->cert, NULL))
|
||||
return E_CERT_CA;
|
||||
else /* XXX more here */
|
||||
return E_CERT_USER;
|
||||
}
|
||||
|
@ -37,6 +37,13 @@ typedef struct _ECert ECert;
|
||||
typedef struct _ECertClass ECertClass;
|
||||
typedef struct _ECertPrivate ECertPrivate;
|
||||
|
||||
typedef enum {
|
||||
E_CERT_CA,
|
||||
E_CERT_CONTACT,
|
||||
E_CERT_SITE,
|
||||
E_CERT_USER
|
||||
} ECertType;
|
||||
|
||||
struct _ECert {
|
||||
GObject parent;
|
||||
|
||||
@ -57,11 +64,20 @@ struct _ECertClass {
|
||||
GType e_cert_get_type (void);
|
||||
|
||||
ECert* e_cert_new (CERTCertificate *cert);
|
||||
ECert* e_cert_new_from_der (char *data, guint32 len);
|
||||
|
||||
const char* e_cert_get_nickname (ECert *cert);
|
||||
const char* e_cert_get_email (ECert *cert);
|
||||
const char* e_cert_get_org (ECert *cert);
|
||||
const char* e_cert_get_cn (ECert *cert);
|
||||
CERTCertificate* e_cert_get_internal_cert (ECert *cert);
|
||||
|
||||
gboolean e_cert_get_raw_der (ECert *cert, char **data, guint32 *len);
|
||||
const char* e_cert_get_nickname (ECert *cert);
|
||||
const char* e_cert_get_email (ECert *cert);
|
||||
const char* e_cert_get_org (ECert *cert);
|
||||
const char* e_cert_get_cn (ECert *cert);
|
||||
const char* e_cert_get_subject_name (ECert *cert);
|
||||
const char* e_cert_get_issuer_name (ECert *cert);
|
||||
|
||||
gboolean e_cert_mark_for_deletion (ECert *cert);
|
||||
|
||||
ECertType e_cert_get_cert_type (ECert *cert);
|
||||
|
||||
gboolean e_cert_is_ca_cert (ECert *cert);
|
||||
#endif /* _E_CERT_H_ */
|
||||
|
@ -7,6 +7,7 @@ INCLUDES= \
|
||||
|
||||
TEST_LIBS= \
|
||||
$(top_builddir)/smime/lib/libessmime.la \
|
||||
-L/home/toshok/src/mozilla/mozilla/dist/lib \
|
||||
$(CERT_UI_LIBS)
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
|
||||
#include <libgnomeui/gnome-ui-init.h>
|
||||
#include "e-cert-db.h"
|
||||
|
||||
int
|
||||
@ -6,19 +7,12 @@ main (int argc, char **argv)
|
||||
{
|
||||
ECertDB *db;
|
||||
|
||||
gnome_program_init ();
|
||||
|
||||
g_type_init ();
|
||||
|
||||
if (SECSuccess != NSS_InitReadWrite ("/home/toshok/.mozilla/default/xuvq7jx3.slt")) {
|
||||
g_error ("NSS_InitReadWrite failed");
|
||||
}
|
||||
|
||||
STAN_LoadDefaultNSS3TrustDomain();
|
||||
|
||||
db = e_cert_db_peek ();
|
||||
|
||||
printf ("default_trust_domain = %p\n", STAN_GetDefaultTrustDomain());
|
||||
printf ("default_crypto_context = %p\n", STAN_GetDefaultCryptoContext());
|
||||
|
||||
if (!e_cert_db_import_certs_from_file (db, "ca.crt", E_CERT_CA, NULL /* XXX */)) {
|
||||
g_warning ("CA cert import failed");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user