aboutsummaryrefslogtreecommitdiffstats
path: root/smime/lib/e-cert-db.c
diff options
context:
space:
mode:
Diffstat (limited to 'smime/lib/e-cert-db.c')
-rw-r--r--smime/lib/e-cert-db.c1077
1 files changed, 0 insertions, 1077 deletions
diff --git a/smime/lib/e-cert-db.c b/smime/lib/e-cert-db.c
deleted file mode 100644
index 5acdf4e847..0000000000
--- a/smime/lib/e-cert-db.c
+++ /dev/null
@@ -1,1077 +0,0 @@
-/* -*- 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.
- *
- */
-
-/* XXX toshok why oh *why* god WHY did they do this? no fucking
- sense */
-/* private NSS defines used by PSM */
-/* (must be declated before cert.h) */
-#define CERT_NewTempCertificate __CERT_NewTempCertificate
-#define CERT_AddTempCertToPerm __CERT_AddTempCertToPerm
-
-#include "e-cert-db.h"
-#include "e-cert-trust.h"
-
-#include "gmodule.h"
-
-#include "nss.h"
-#include "pk11func.h"
-#include "secmod.h"
-#include "certdb.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>
-#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;
- gboolean has_roots;
- PK11SlotList *list;
-
- 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");
- }
-
- /*
- * check to see if you have a rootcert module installed
- */
-
- has_roots = FALSE;
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
- if (list) {
- PK11SlotListElement *le;
-
- for (le = list->head; le; le = le->next) {
- if (PK11_HasRootCerts(le->slot)) {
- has_roots = TRUE;
- break;
- }
- }
- }
-
- if (!has_roots) {
- /* grovel in various places for mozilla's built-in
- cert module.
-
- XXX yes this is gross. *sigh*
- */
- char *paths_to_check[] = {
- "/usr/lib",
- "/usr/lib/mozilla",
- };
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (paths_to_check); i ++) {
- char *dll_path = g_module_build_path (paths_to_check [i],
- "nssckbi");
-
- if (g_file_test (dll_path, G_FILE_TEST_EXISTS)) {
- SECMOD_AddNewModule("Mozilla Root Certs",dll_path, 0, 0);
- g_free (dll_path);
- break;
- }
-
- g_free (dll_path);
- }
- }
-}
-
-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 */
- CERT_DestroyCertificate(any_cert);
- return NULL;
- }
-
- if (SECSuccess != CERT_FilterCertListByUsage(certlist, certUsageEmailRecipient, PR_FALSE)) {
- /* XXX gerror */
- CERT_DestroyCertificate(any_cert);
- /* XXX free certlist? */
- return NULL;
- }
-
- if (CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) {
- /* XXX gerror */
- CERT_DestroyCertificate(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;
- CERTCertTrust trust;
-
- 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()));*/
-
- e_cert_trust_init (&trust);
- e_cert_trust_set_valid_ca (&trust);
- e_cert_trust_add_ca_trust (&trust,
-#if 1
- /* XXX we need that ui working i guess. */
- 0, 0, 0
-#else
- trustBits & nsIX509CertDB::TRUSTED_SSL,
- trustBits & nsIX509CertDB::TRUSTED_EMAIL,
- trustBits & nsIX509CertDB::TRUSTED_OBJSIGN
-#endif
-);
-
- srv = CERT_AddTempCertToPerm(tmpCert,
- nickname,
- &trust);
-
- 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. */
- e_cert_trust_init (&trust);
- e_cert_trust_set_valid_ca (&trust);
- e_cert_trusts_add_ca_trust (&trust, 0, 0, 0);
- for (PRUint32 i=0; i<numCerts; i++) {
- if (i == selCertIndex)
- continue;
-
- 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. */
- CERTCertTrust trust;
-
- e_cert_trust_init_with_values (&trust, 0, 0, 0);
- srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(),
- cert, &trust);
- }
-
- /*PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("cert deleted: %d", srv));*/
- 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)
-{
- /*nsNSSShutDownPreventionLock locker;*/
- SECStatus srv = SECFailure;
- gboolean rv = TRUE;
- CERTCertificate * cert;
- SECItem **rawCerts;
- int numcerts;
- int i;
- PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- CERTDERCerts *certCollection = e_cert_db_get_certs_from_package (arena, data, length);
-
- if (!certCollection) {
- /* XXX g_error */
-
- PORT_FreeArena(arena, PR_FALSE);
- return FALSE;
- }
-
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), certCollection->rawCerts,
- (char *)NULL, PR_FALSE, PR_TRUE);
- if (!cert) {
- /* XXX g_error */
- rv = FALSE;
- goto loser;
- }
- numcerts = certCollection->numcerts;
- rawCerts = (SECItem **) PORT_Alloc(sizeof(SECItem *) * numcerts);
- if ( !rawCerts ) {
- /* XXX g_error */
- rv = FALSE;
- goto loser;
- }
-
- for ( i = 0; i < numcerts; i++ ) {
- rawCerts[i] = &certCollection->rawCerts[i];
- }
-
- srv = CERT_ImportCerts(CERT_GetDefaultCertDB(), certUsageEmailSigner,
- numcerts, rawCerts, NULL, PR_TRUE, PR_FALSE,
- NULL);
- if ( srv != SECSuccess ) {
- /* XXX g_error */
- rv = FALSE;
- goto loser;
- }
- srv = CERT_SaveSMimeProfile(cert, NULL, NULL);
- PORT_Free(rawCerts);
- loser:
- if (cert)
- CERT_DestroyCertificate(cert);
- if (arena)
- PORT_FreeArena(arena, PR_TRUE);
- 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
-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
-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;
-}