Commit 4e4c1676 authored by Chris Toshok's avatar Chris Toshok Committed by Chris Toshok

mostly implement a viewer for certificates.

2003-11-26  Chris Toshok  <toshok@ximian.com>

	* gui/certificate-viewer.[ch]: mostly implement a viewer for
	certificates.

	* gui/smime-ui.glade: fingerprints-sh1 -> fingerprints-sha1.

	* gui/certificate-manager.c (import_your): new function, use
	e-pkcs12 to implement it.
	(initialize_yourcerts_ui): hook up the import button.
	(view_contact): new function, bring up the certificate viewer.
	(initialize_contactcerts_ui): hook up the view button.
	(view_ca): new function, bring up the certificate viewer.
	(initialize_authoritycerts_ui): hook up the view button.

	* gui/Makefile.am (libevolution_smime_la_SOURCES): add
	certificate-viewer.[ch]

	* lib/e-cert.c (e_cert_dispose): free all the new cached foo.
	(e_cert_populate): populate all the new cached foo.
	(e_cert_get_issuer_cn): new function.
	(e_cert_get_issuer_org): same.
	(e_cert_get_issuer_org_unit): same.
	(e_cert_get_issued_on_time): same.
	(e_cert_get_issued_on): same.
	(e_cert_get_expires_on_time): same.
	(e_cert_get_expires_on): same.
	(e_cert_get_serial_number): same.
	(e_cert_get_sha1_fingerprint): same.
	(e_cert_get_md5_fingerprint): same.

	* lib/e-cert.h: add prototypes for lots more accessors.

	* lib/e-cert-db.c (e_cert_db_find_cert_by_key): fix typo.
	(e_cert_db_find_cert_by_email_address): call
	CERT_DestroyCertificate to free the cert.
	(default_nickname): new function.
	(e_cert_db_import_user_cert): implement.
	(e_cert_db_import_server_cert): add blurb.

	* lib/e-pkcs12.[ch]: new files.

	* lib/Makefile.am (libessmime_la_SOURCES): add e-pkcs12.[ch]

svn path=/trunk/; revision=23486
parent 30ff908f
2003-11-26 Chris Toshok <toshok@ximian.com>
* gui/certificate-viewer.[ch]: mostly implement a viewer for
certificates.
* gui/smime-ui.glade: fingerprints-sh1 -> fingerprints-sha1.
* gui/certificate-manager.c (import_your): new function, use
e-pkcs12 to implement it.
(initialize_yourcerts_ui): hook up the import button.
(view_contact): new function, bring up the certificate viewer.
(initialize_contactcerts_ui): hook up the view button.
(view_ca): new function, bring up the certificate viewer.
(initialize_authoritycerts_ui): hook up the view button.
* gui/Makefile.am (libevolution_smime_la_SOURCES): add
certificate-viewer.[ch]
* lib/e-cert.c (e_cert_dispose): free all the new cached foo.
(e_cert_populate): populate all the new cached foo.
(e_cert_get_issuer_cn): new function.
(e_cert_get_issuer_org): same.
(e_cert_get_issuer_org_unit): same.
(e_cert_get_issued_on_time): same.
(e_cert_get_issued_on): same.
(e_cert_get_expires_on_time): same.
(e_cert_get_expires_on): same.
(e_cert_get_serial_number): same.
(e_cert_get_sha1_fingerprint): same.
(e_cert_get_md5_fingerprint): same.
* lib/e-cert.h: add prototypes for lots more accessors.
* lib/e-cert-db.c (e_cert_db_find_cert_by_key): fix typo.
(e_cert_db_find_cert_by_email_address): call
CERT_DestroyCertificate to free the cert.
(default_nickname): new function.
(e_cert_db_import_user_cert): implement.
(e_cert_db_import_server_cert): add blurb.
* lib/e-pkcs12.[ch]: new files.
* lib/Makefile.am (libessmime_la_SOURCES): add e-pkcs12.[ch]
2003-11-12 Not Zed <NotZed@Ximian.com>
* gui/smime-ui.glade: added cert_selector widget to be placed
......
......@@ -23,6 +23,8 @@ noinst_LTLIBRARIES = libevolution-smime.la
libevolution_smime_la_SOURCES = \
certificate-manager.c \
certificate-manager.h \
certificate-viewer.c \
certificate-viewer.h \
e-cert-selector.c \
e-cert-selector.h
......
......@@ -29,9 +29,11 @@
#include <glade/glade.h>
#include "evolution-config-control.h"
#include "certificate-manager.h"
#include "certificate-viewer.h"
#include "e-cert.h"
#include "e-cert-db.h"
#include "e-pkcs12.h"
#include "nss.h"
#include <cms.h>
......@@ -114,6 +116,26 @@ handle_selection_changed (GtkTreeSelection *selection,
gtk_widget_set_sensitive (view_button, cert_selected);
}
static void
import_your (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));
EPKCS12 *pkcs12 = e_pkcs12_new ();
if (e_pkcs12_import_from_file (pkcs12, filename, NULL /* XXX */)) {
/* 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_USER);
load_certs (cfm, E_CERT_USER, add_user_cert);
}
}
gtk_widget_destroy (filesel);
}
static void
yourcerts_selection_changed (GtkTreeSelection *selection, CertificateManagerData *cfm)
{
......@@ -170,7 +192,7 @@ initialize_yourcerts_ui (CertificateManagerData *cfm)
g_signal_connect (selection, "changed", G_CALLBACK (yourcerts_selection_changed), cfm);
if (cfm->import_your_button) {
/* g_signal_connect */
g_signal_connect (cfm->import_your_button, "clicked", G_CALLBACK (import_your), cfm);
}
if (cfm->delete_your_button) {
......@@ -190,6 +212,26 @@ initialize_yourcerts_ui (CertificateManagerData *cfm)
}
}
static void
view_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)
certificate_viewer_show (cert);
}
}
static void
import_contact (GtkWidget *widget, CertificateManagerData *cfm)
{
......@@ -297,6 +339,9 @@ 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->view_contact_button)
g_signal_connect (cfm->view_contact_button, "clicked", G_CALLBACK (view_contact), cfm);
if (cfm->import_contact_button)
g_signal_connect (cfm->import_contact_button, "clicked", G_CALLBACK (import_contact), cfm);
......@@ -324,6 +369,26 @@ iter_string_compare (GtkTreeModel *model,
return g_utf8_collate (string1, string2);
}
static void
view_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)
certificate_viewer_show (cert);
}
}
static void
import_ca (GtkWidget *widget, CertificateManagerData *cfm)
{
......@@ -421,6 +486,9 @@ initialize_authoritycerts_ui (CertificateManagerData *cfm)
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cfm->authoritycerts_treeview));
g_signal_connect (selection, "changed", G_CALLBACK (authoritycerts_selection_changed), cfm);
if (cfm->view_ca_button)
g_signal_connect (cfm->view_ca_button, "clicked", G_CALLBACK (view_ca), cfm);
if (cfm->import_ca_button)
g_signal_connect (cfm->import_ca_button, "clicked", G_CALLBACK (import_ca), cfm);
......
/* -*- 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.
*
*/
#include "certificate-viewer.h"
#include <gtk/gtk.h>
#include <libgnome/gnome-i18n.h>
#include <glade/glade.h>
#define GLADE_FILE_NAME "smime-ui.glade"
typedef struct {
GladeXML *gui;
GtkWidget *dialog;
} CertificateViewerData;
static void
free_data (gpointer data, GObject *where_the_object_was)
{
CertificateViewerData *cvm = data;
g_object_unref (cvm->gui);
g_free (cvm);
}
GtkWidget*
certificate_viewer_show (ECert *cert)
{
CertificateViewerData *cvm_data;
CERTCertificate *mcert;
GtkWidget *label;
const char *text;
mcert = e_cert_get_internal_cert (cert);
cvm_data = g_new0 (CertificateViewerData, 1);
cvm_data->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, NULL, NULL);
cvm_data->dialog = glade_xml_get_widget (cvm_data->gui, "certificate-viewer-dialog");
/* issued to */
if (e_cert_get_cn (cert)) {
label = glade_xml_get_widget (cvm_data->gui, "issued-to-cn");
gtk_label_set_text (GTK_LABEL (label), e_cert_get_cn (cert));
}
if (e_cert_get_org (cert)) {
label = glade_xml_get_widget (cvm_data->gui, "issued-to-o");
gtk_label_set_text (GTK_LABEL (label), e_cert_get_org (cert));
}
if (e_cert_get_org_unit (cert)) {
label = glade_xml_get_widget (cvm_data->gui, "issued-to-ou");
gtk_label_set_text (GTK_LABEL (label), e_cert_get_org_unit (cert));
}
text = e_cert_get_serial_number (cert);
label = glade_xml_get_widget (cvm_data->gui, "issued-to-serial");
gtk_label_set_text (GTK_LABEL (label), text);
/* issued by */
if (e_cert_get_issuer_cn (cert)) {
label = glade_xml_get_widget (cvm_data->gui, "issued-by-cn");
gtk_label_set_text (GTK_LABEL (label), e_cert_get_issuer_cn (cert));
}
if (e_cert_get_issuer_org (cert)) {
label = glade_xml_get_widget (cvm_data->gui, "issued-by-o");
gtk_label_set_text (GTK_LABEL (label), e_cert_get_issuer_org (cert));
}
if (e_cert_get_issuer_org_unit (cert)) {
label = glade_xml_get_widget (cvm_data->gui, "issued-by-ou");
gtk_label_set_text (GTK_LABEL (label), e_cert_get_issuer_org_unit (cert));
}
/* validity */
if (e_cert_get_issued_on (cert)) {
label = glade_xml_get_widget (cvm_data->gui, "validity-issued-on");
gtk_label_set_text (GTK_LABEL (label), e_cert_get_issued_on (cert));
}
if (e_cert_get_expires_on (cert)) {
label = glade_xml_get_widget (cvm_data->gui, "validity-expires-on");
gtk_label_set_text (GTK_LABEL (label), e_cert_get_expires_on (cert));
}
/* fingerprints */
text = e_cert_get_sha1_fingerprint (cert);
label = glade_xml_get_widget (cvm_data->gui, "fingerprints-sha1");
gtk_label_set_text (GTK_LABEL (label), text);
text = e_cert_get_md5_fingerprint (cert);
label = glade_xml_get_widget (cvm_data->gui, "fingerprints-md5");
gtk_label_set_text (GTK_LABEL (label), text);
g_object_weak_ref (G_OBJECT (cvm_data->dialog), free_data, cvm_data);
g_signal_connect (cvm_data->dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (cvm_data->dialog);
return cvm_data->dialog;
}
/* -*- 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 _CERTIFICATE_VIEWER_H_
#define _CERTIFICATE_VIEWER_H
#include <gtk/gtkwidget.h>
#include "e-cert.h"
GtkWidget* certificate_viewer_show (ECert *cert);
#endif /* _CERTIFICATE_VIEWER_H_ */
......@@ -745,7 +745,7 @@
</child>
<child>
<widget class="GtkLabel" id="fingerprints-sh1">
<widget class="GtkLabel" id="fingerprints-sha1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">&lt;Not Part of Certificate&gt;</property>
......
......@@ -25,4 +25,6 @@ libessmime_la_SOURCES = \
e-cert-trust.c \
e-cert-trust.h \
e-cert-db.c \
e-cert-db.h
e-cert-db.h \
e-pkcs12.c \
e-pkcs12.h
......@@ -68,7 +68,10 @@
#include "nss.h"
#include "pk11func.h"
#include "certdb.h"
#include <e-util/e-dialog-utils.h>
#include "plstr.h"
#include "prprf.h"
#include "prmem.h"
#include "e-util/e-dialog-utils.h"
#include <gtk/gtkmessagedialog.h>
#include <libgnome/gnome-i18n.h>
#include <fcntl.h>
......@@ -249,7 +252,7 @@ e_cert_db_find_cert_by_key (ECertDB *certdb,
moduleID = NS_NSS_GET_LONG(keyItem.data);
slotID = NS_NSS_GET_LONG(&keyItem.data[NS_NSS_LONG]);
/8 build the issuer/SN structure*/
/* 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];
......@@ -312,21 +315,21 @@ e_cert_db_find_cert_by_email_address (ECertDB *certdb,
PR_Now(), PR_TRUE);
if (!certlist) {
/* XXX gerror */
/* XXX free any_cert */
CERT_DestroyCertificate(any_cert);
return NULL;
}
if (SECSuccess != CERT_FilterCertListByUsage(certlist, certUsageEmailRecipient, PR_FALSE)) {
/* XXX gerror */
/* XXX free any_cert */
/* XXX free certlist */
CERT_DestroyCertificate(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 */
CERT_DestroyCertificate(any_cert);
/* XXX free certlist? */
return NULL;
}
......@@ -665,11 +668,208 @@ e_cert_db_import_email_cert (ECertDB *certdb,
return rv;
}
static char *
default_nickname (CERTCertificate *cert)
{
/* nsNSSShutDownPreventionLock locker; */
char *username = NULL;
char *caname = NULL;
char *nickname = NULL;
char *tmp = NULL;
int count;
char *nickFmt=NULL, *nickFmtWithNum = NULL;
CERTCertificate *dummycert;
PK11SlotInfo *slot=NULL;
CK_OBJECT_HANDLE keyHandle;
CERTCertDBHandle *defaultcertdb = CERT_GetDefaultCertDB();
username = CERT_GetCommonName(&cert->subject);
if ( username == NULL )
username = PL_strdup("");
if ( username == NULL )
goto loser;
caname = CERT_GetOrgName(&cert->issuer);
if ( caname == NULL )
caname = PL_strdup("");
if ( caname == NULL )
goto loser;
count = 1;
nickFmt = "%1$s's %2$s ID";
nickFmtWithNum = "%1$s's %2$s ID #%3$d";
nickname = PR_smprintf(nickFmt, username, caname);
/*
* We need to see if the private key exists on a token, if it does
* then we need to check for nicknames that already exist on the smart
* card.
*/
slot = PK11_KeyForCertExists(cert, &keyHandle, NULL);
if (slot == NULL) {
goto loser;
}
if (!PK11_IsInternal(slot)) {
tmp = PR_smprintf("%s:%s", PK11_GetTokenName(slot), nickname);
PR_Free(nickname);
nickname = tmp;
tmp = NULL;
}
tmp = nickname;
while ( 1 ) {
if ( count > 1 ) {
nickname = PR_smprintf("%s #%d", tmp, count);
}
if ( nickname == NULL )
goto loser;
if (PK11_IsInternal(slot)) {
/* look up the nickname to make sure it isn't in use already */
dummycert = CERT_FindCertByNickname(defaultcertdb, nickname);
} else {
/*
* Check the cert against others that already live on the smart
* card.
*/
dummycert = PK11_FindCertFromNickname(nickname, NULL);
if (dummycert != NULL) {
/*
* Make sure the subject names are different.
*/
if (CERT_CompareName(&cert->subject, &dummycert->subject) == SECEqual) {
/*
* There is another certificate with the same nickname and
* the same subject name on the smart card, so let's use this
* nickname.
*/
CERT_DestroyCertificate(dummycert);
dummycert = NULL;
}
}
}
if ( dummycert == NULL )
goto done;
/* found a cert, destroy it and loop */
CERT_DestroyCertificate(dummycert);
if (tmp != nickname) PR_Free(nickname);
count++;
} /* end of while(1) */
loser:
if ( nickname ) {
PR_Free(nickname);
}
nickname = NULL;
done:
if ( caname ) {
PR_Free(caname);
}
if ( username ) {
PR_Free(username);
}
if (slot != NULL) {
PK11_FreeSlot(slot);
if (nickname != NULL) {
tmp = nickname;
nickname = strchr(tmp, ':');
if (nickname != NULL) {
nickname++;
nickname = PL_strdup(nickname);
PR_Free(tmp);
tmp = NULL;
} else {
nickname = tmp;
tmp = NULL;
}
}
}
PR_FREEIF(tmp);
return(nickname);
}
gboolean
e_cert_db_import_user_cert (ECertDB *certdb,
char *data, guint32 length,
GError **error)
{
/* nsNSSShutDownPreventionLock locker;*/
PK11SlotInfo *slot;
char * nickname = NULL;
gboolean rv = FALSE;
int numCACerts;
SECItem *CACerts;
CERTDERCerts * collectArgs;
PRArenaPool *arena;
CERTCertificate * cert=NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( arena == NULL ) {
/* XXX g_error */
goto loser;
}
collectArgs = e_cert_db_get_certs_from_package (arena, data, length);
if (!collectArgs) {
/* XXX g_error */
goto loser;
}
cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), collectArgs->rawCerts,
(char *)NULL, PR_FALSE, PR_TRUE);
if (!cert) {
/* XXX g_error */
goto loser;
}
slot = PK11_KeyForCertExists(cert, NULL, NULL);
if ( slot == NULL ) {
/* XXX g_error */
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 {
nickname = default_nickname(cert);
}
/* user wants to import the cert */
slot = PK11_ImportCertForKey(cert, nickname, NULL);
if (!slot) {
/* XXX g_error */
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 (arena) {
PORT_FreeArena(arena, PR_FALSE);
}
if ( cert ) {
CERT_DestroyCertificate(cert);
}
return rv;
}
gboolean
......@@ -677,6 +877,9 @@ e_cert_db_import_server_cert (ECertDB *certdb,
char *data, guint32 length,
GError **error)
{
/* not c&p'ing this over at the moment, as we don't have a UI
for server certs anyway */
return FALSE;
}
gboolean
......
......@@ -55,10 +55,16 @@
*
*/
#include <time.h>
#include <libgnome/gnome-i18n.h>
#include <gal/util/e-util.h> /* for e_utf8_strftime, what about e_time_format_time? */
#include "e-cert.h"
#include "e-cert-trust.h"
#include "pk11func.h"
#include "certdb.h"
#include "hasht.h"
struct _ECertPrivate {
CERTCertificate *cert;
......@@ -66,8 +72,24 @@ struct _ECertPrivate {
/* pointers we cache since the nss implementation allocs the
string */
char *org_name;
char *org_unit_name;
char *cn;
char *issuer_org_name;
char *issuer_org_unit_name;
char *issuer_cn;
PRTime issued_on;
PRTime expires_on;
char *issued_on_string;
char *expires_on_string;
char *serial_number;
char *sha1_fingerprint;
char *md5_fingerprint;
gboolean delete;
};
......@@ -84,9 +106,30 @@ e_cert_dispose (GObject *object)
if (ec->priv->org_name)
PORT_Free (ec->priv->org_name);
if (ec->priv->org_unit_name)
PORT_Free (ec->priv->org_unit_name);
if (ec->priv->cn)
PORT_Free (ec->priv->cn);
if (ec->priv->issuer_org_name)
PORT_Free (ec->priv->issuer_org_name);
if (ec->priv->issuer_org_unit_name)
PORT_Free (ec->priv->issuer_org_unit_name);
if (ec->priv->issuer_cn)
PORT_Free (ec->priv->issuer_cn);
if (ec->priv->issued_on_string)
PORT_Free (ec->priv->issued_on_string);
if (ec->priv->expires_on_string)
PORT_Free (ec->priv->expires_on_string);
if (ec->priv->serial_number)
PORT_Free (ec->priv->serial_number);
if (ec->priv->sha1_fingerprint)
PORT_Free (ec->priv->sha1_fingerprint);
if (ec->priv->md5_fingerprint)
PORT_Free (ec->priv->md5_fingerprint);
if (ec->priv->delete) {
printf ("attempting to delete cert marked for deletion\n");
if (e_cert_get_cert_type (ec) == E_CERT_USER) {
......@@ -154,8 +197,61 @@ static void
e_cert_populate (ECert *cert)
{
CERTCertificate *c = cert->priv->cert;
unsigned char fingerprint[20];
SECItem fpItem;
cert->priv->org_name = CERT_GetOrgName (&c->subject);
cert->priv->org_unit_name = CERT_GetOrgUnitName (&c->subject);
cert->priv->issuer_org_name = CERT_GetOrgName (&c->issuer);
cert->priv->issuer_org_unit_name = CERT_GetOrgUnitName (&c->issuer);
cert->priv->cn = CERT_GetCommonName (&c->subject);
cert->priv->issuer_cn = CERT_GetCommonName (&c->issuer);
if (SECSuccess == CERT_GetCertTimes (c, &cert->priv->issued_on, &cert->priv->expires_on)) {
PRExplodedTime explodedTime;
struct tm exploded_tm;
char buf[32];
PR_ExplodeTime (cert->priv->issued_on, PR_LocalTimeParameters, &explodedTime);
exploded_tm.tm_sec = explodedTime.tm_sec;
exploded_tm.tm_min = explodedTime.tm_min;
exploded_tm.tm_hour = explodedTime.tm_hour;
exploded_tm.tm_mday = explodedTime.tm_mday;
exploded_tm.tm_mon = explodedTime.tm_month;
exploded_tm.tm_year = explodedTime.tm_year - 1900;
e_utf8_strftime (buf, sizeof(buf), _("%d/%m/%Y"), &exploded_tm);
cert->priv->issued_on_string = g_strdup (buf);
PR_ExplodeTime (cert->priv->expires_on, PR_LocalTimeParameters, &explodedTime);
exploded_tm.tm_sec = explodedTime.tm_sec;
exploded_tm.tm_min = explodedTime.tm_min;
exploded_tm.tm_hour = explodedTime.tm_hour;
exploded_tm.tm_mday = explodedTime.tm_mday;
exploded_tm.tm_mon = explodedTime.tm_month;
exploded_tm.tm_year = explodedTime.tm_year - 1900;
e_utf8_strftime (buf, sizeof(buf), _("%d/%m/%Y"), &exploded_tm);
cert->priv->expires_on_string = g_strdup (buf);
}
cert->priv->serial_number = CERT_Hexify (&cert->priv->cert->serialNumber, TRUE);
memset(fingerprint, 0, sizeof fingerprint);
PK11_HashBuf(SEC_OID_SHA1, fingerprint,
cert->priv->cert->derCert.data,
cert->priv->cert->derCert.len);