diff options
Diffstat (limited to 'smime/lib/e-cert-db.c')
-rw-r--r-- | smime/lib/e-cert-db.c | 1077 |
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; -} |