/cpw/ljfisher/ssl_client_auth: d97cc2ae2ceb: Collect related crt...

Lucas Fisher lucas.fisher at gmail.com
Mon Oct 8 19:04:49 EDT 2012


Changeset: d97cc2ae2ceb5dff779062b1167e585340db744a
Author:	 Lucas Fisher <lucas.fisher at gmail.com>
Date:	 2012-10-08 18:02 -0400
Branch:	 cpw.ljfisher.ssl_client_auth
URL: http://hg.pidgin.im/cpw/ljfisher/ssl_client_auth/rev/d97cc2ae2ceb

Description:

Collect related crts and keys into a new PurpleCredential to better handle multiple keys in PKCS12 files.

diffstat:

 libpurple/Makefile.am              |    2 +
 libpurple/credential.c             |   43 +++
 libpurple/credential.h             |   63 +++++
 libpurple/pkcs12.c                 |   56 ++--
 libpurple/pkcs12.h                 |   20 +-
 libpurple/plugins/ssl/ssl-gnutls.c |  408 ++++++++++++++++++++++++++++++++----
 libpurple/privatekey.h             |    1 +
 pidgin/gtkcertmgr.c                |   72 ++++-
 8 files changed, 558 insertions(+), 107 deletions(-)

diffs (truncated from 991 to 300 lines):

diff --git a/libpurple/Makefile.am b/libpurple/Makefile.am
--- a/libpurple/Makefile.am
+++ b/libpurple/Makefile.am
@@ -46,6 +46,7 @@ purple_coresources = \
 	connection.c \
 	conversation.c \
 	core.c \
+	credential.c \
 	debug.c \
 	desktopitem.c \
 	eventloop.c \
@@ -114,6 +115,7 @@ purple_coreheaders = \
 	connection.h \
 	conversation.h \
 	core.h \
+	credential.h \
 	dbus-maybe.h \
 	debug.h \
 	desktopitem.h \
diff --git a/libpurple/credential.c b/libpurple/credential.c
new file mode 100644
--- /dev/null
+++ b/libpurple/credential.c
@@ -0,0 +1,43 @@
+/**
+ * @file credential.c CREDENTIAL API
+ * @ingroup core
+ */
+
+/*
+ *
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+
+#include "credential.h"
+
+void purple_credential_destroy(PurpleCredential *cred)
+{
+	g_return_if_fail(NULL == cred);
+	purple_certificate_destroy_list(cred->crts);
+	purple_privatekey_destroy(cred->key);
+}
+
+void purple_credential_destroy_list(GList *creds)
+{
+	g_return_if_fail(NULL == creds);
+	g_list_foreach(creds, (GFunc)purple_credential_destroy, NULL);
+	g_list_free(creds);
+}
diff --git a/libpurple/credential.h b/libpurple/credential.h
new file mode 100644
--- /dev/null
+++ b/libpurple/credential.h
@@ -0,0 +1,63 @@
+/**
+ * @file credential.h CREDENTIAL API
+ * @ingroup core
+ * @see 
+ * @since 3.0.0
+ *
+ * Purple credentials are basically a convienent means to carry around a 
+ * key and its associated certificates in one object.
+ */
+
+/*
+ *
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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.
+ *a
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ */
+
+#ifndef _PURPLE_CREDENTIAL_H
+#define _PURPLE_CREDENTIAL_H
+
+#include <glib.h>
+#include "privatekey.h"
+#include "certificate.h"
+
+typedef struct _PurpleCredential PurpleCredential;
+
+struct _PurpleCredential
+{
+	GList *crts;            /* certificate chain starting with end point cert */
+	PurplePrivateKey *key;	/* private key for end point cert */
+};
+
+/**
+ * Destroy a credential and all certificates and keys referenced by it.
+ *
+ * @param cred PurpleCredential to destroy.
+ */
+void purple_credential_destroy(PurpleCredential *cred);
+
+/**
+ * Destroy a list of credentials.
+ *
+ * @param List of credentials.
+ */
+void purple_credential_destroy_list(GList *creds);
+
+#endif  /* _PURPLE_CREDENTIAL_H*/
diff --git a/libpurple/pkcs12.c b/libpurple/pkcs12.c
--- a/libpurple/pkcs12.c
+++ b/libpurple/pkcs12.c
@@ -33,6 +33,7 @@
 #include "request.h"
 #include "signals.h"
 #include "util.h"
+#include "credential.h"
 
 /** List holding pointers to all registered private key schemes */
 static GList *pkcs12_schemes = NULL;
@@ -40,15 +41,14 @@ static GList *pkcs12_schemes = NULL;
 gboolean
 purple_pkcs12_import(PurplePkcs12Scheme *scheme,
 		     const gchar *filename, const gchar *password,
-		     GList **crts, PurplePrivateKey **key)
+		     GList **credentials)
 {
 	g_return_val_if_fail(scheme, FALSE);
 	g_return_val_if_fail(filename, FALSE);
 	g_return_val_if_fail(password, FALSE);
-	g_return_val_if_fail(crts, FALSE);
-	g_return_val_if_fail(key, FALSE);
+	g_return_val_if_fail(credentials, FALSE);
 
-	return (scheme->import_pkcs12)(filename, password, crts, key);
+	return (scheme->import_pkcs12)(filename, password, credentials);
 }
 
 gboolean
@@ -67,10 +67,12 @@ gboolean
 purple_pkcs12_import_to_pool(PurplePkcs12Scheme *scheme, const gchar *filename, const gchar *password,
 							 PurpleCertificatePool *crtpool, PurplePrivateKeyPool *keypool)
 {
-	GList *crts;
+	GList *creds;
 	PurplePrivateKey *key;
 	GList *i;
 	gchar *id;
+	gboolean result = FALSE;
+	GList *creditem;
 
 	g_return_val_if_fail(scheme, FALSE);
 	g_return_val_if_fail(filename, FALSE);
@@ -79,33 +81,37 @@ purple_pkcs12_import_to_pool(PurplePkcs1
 	g_return_val_if_fail(keypool, FALSE);
 
 
-	if (!purple_pkcs12_import(scheme, filename, password, &crts, &key))
+	if (!purple_pkcs12_import(scheme, filename, password, &creds))
 		return FALSE;
 
-	for (i = g_list_first(crts); NULL != g_list_next(i); i = g_list_next(i)) {
-		PurpleCertificate *crt = (PurpleCertificate*)i->data;
+	for (creditem = g_list_first(creds);
+			NULL != creditem; creditem = g_list_next(creditem)) {
+		PurpleCredential *cred = (PurpleCredential*)creditem->data;
 
-		id = purple_certificate_get_unique_id(crt);
+		for (i = g_list_first(cred->crts); NULL != i; i = g_list_next(i)) {
+			PurpleCertificate *crt = (PurpleCertificate*)i->data;
+
+			id = purple_certificate_get_unique_id(crt);
+			if (NULL == id)
+				goto done;
+
+			if (!purple_certificate_pool_store(crtpool, id, crt))
+				goto done;
+		}
+
+		id = purple_privatekey_get_unique_id(cred->key);
 		if (NULL == id)
-			goto error;
+			goto done;
 
-		if (!purple_certificate_pool_store(crtpool, id, crt))
-			goto error;
+		if (!purple_privatekey_pool_store(keypool, id, key, password))
+			goto done;
 	}
 
-	id = purple_privatekey_get_unique_id(key);
-	if (NULL == id)
-		goto error;
+	result = TRUE;
 
-	if (!purple_privatekey_pool_store(keypool, id, key, password))
-		goto error;
-
-	return TRUE;
-
-error:
-	purple_certificate_destroy_list(crts);
-	purple_privatekey_destroy(key);
-	return FALSE;
+done:
+	purple_credential_destroy_list(creds);
+	return result;
 }
 
 void
@@ -144,7 +150,7 @@ purple_pkcs12_request_password(void* han
                         _("Cancel"), cancel_cb,    /* cancel text and callback */
 			NULL, NULL, NULL,          /* account, who, conv */
                         user_data);                /* callback data */
-	g_free(primary); /* TODO: not right */
+	g_free(primary); /* TODO: not right ?? */
 }
 
 /****************************************************************************/
diff --git a/libpurple/pkcs12.h b/libpurple/pkcs12.h
--- a/libpurple/pkcs12.h
+++ b/libpurple/pkcs12.h
@@ -2,7 +2,7 @@
  * @file pkcs12.h PKCS12 API
  * @ingroup core
  * @see 
- * @since 2.2.0
+ * @since 3.0.0
  */
 
 /*
@@ -71,16 +71,12 @@ struct _PurplePkcs12Scheme
 	 *
 	 * @param filename    File path to import from
 	 * @param password    Password protecting the PKCS12 file
-	 * @param crts        List of ptrs to PurpleCertificates from the PKCS12 file.
+	 * @param credentials List of PurpleCredentials from the PKCS12 file.
 	 *                    Must be free'd by caller.
-	 * @param key         PurplePrivateKey from the PKCS12 file.
-	 *                    Must be free'd by caller.
-	 *                    We only support one private key per PKCS12 file since we
-	 *                    are otherwise unable to match the key with its certificate.
 	 * @return TRUE if at least one certificate and key were imported, and FALSE on failure
 	 */
 	gboolean (*import_pkcs12)(const gchar *filename, const gchar *password,
-				  GList **crts, PurplePrivateKey **key);
+				  GList **credentials);
 
 	/**
 	 * Exports PurpleCertificates and PurplePrivateKey to a file
@@ -112,22 +108,20 @@ struct _PurplePkcs12Scheme
  * @param scheme      Scheme to import under
  * @param filename    File path to import from
  * @param password    Password protecting the PKCS12 file
- * @param crts        Certificate chain from the PKCS12 file in the form of a list
+ * @param credentials List of PurpleCredentials. Each credentials contains:
+ *                    Certificate chain from the PKCS12 file in the form of a list
  *                    of ptrs to PurpleCertificates. The chain must be in order.
  *                    The first certificate must be the certificate corresponding to
  *                    key. Each certificate should be followed by the issuer's
  *                    certificate and end at the root CA certificate. The whole chain
  *                    need not be present.
+ *                    The PurplePrivateKey from the PKCS12 file for the certificate chain.
  *                    Must be free'd by caller.
- * @param key         PurplePrivateKey from the PKCS12 file.
- *                    Must be free'd by caller.
- *                    We only support one private key per PKCS12 file since we are
- *                    otherwise unable to match up the key with its certificate.
  * @return TRUE if at least one certificate and key were imported, and FALSE on failure
  */
 gboolean
 purple_pkcs12_import(PurplePkcs12Scheme *scheme, const gchar *filename, const gchar *password,
-		     GList **crts, PurplePrivateKey **key);
+		     GList **credentials);



More information about the Commits mailing list