aboutsummaryrefslogtreecommitdiffstats
path: root/smime/lib/e-cert-db.c
diff options
context:
space:
mode:
authorChris Toshok <toshok@ximian.com>2003-11-26 16:54:48 +0800
committerChris Toshok <toshok@src.gnome.org>2003-11-26 16:54:48 +0800
commit4e4c16760abdbc2ab34b159e52c5c027a1b2ad26 (patch)
tree3011e05a12b84f273ae36b6109293a55fe1aec53 /smime/lib/e-cert-db.c
parent30ff908fcddcf18107d8b0fd39e4504b2a69ef19 (diff)
downloadgsoc2013-evolution-4e4c16760abdbc2ab34b159e52c5c027a1b2ad26.tar
gsoc2013-evolution-4e4c16760abdbc2ab34b159e52c5c027a1b2ad26.tar.gz
gsoc2013-evolution-4e4c16760abdbc2ab34b159e52c5c027a1b2ad26.tar.bz2
gsoc2013-evolution-4e4c16760abdbc2ab34b159e52c5c027a1b2ad26.tar.lz
gsoc2013-evolution-4e4c16760abdbc2ab34b159e52c5c027a1b2ad26.tar.xz
gsoc2013-evolution-4e4c16760abdbc2ab34b159e52c5c027a1b2ad26.tar.zst
gsoc2013-evolution-4e4c16760abdbc2ab34b159e52c5c027a1b2ad26.zip
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
Diffstat (limited to 'smime/lib/e-cert-db.c')
-rw-r--r--smime/lib/e-cert-db.c217
1 files changed, 210 insertions, 7 deletions
diff --git a/smime/lib/e-cert-db.c b/smime/lib/e-cert-db.c
index 02959f3505..a597a305af 100644
--- a/smime/lib/e-cert-db.c
+++ b/smime/lib/e-cert-db.c
@@ -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