cpw.ljfisher.ssl_client_auth: 3a04ab1f: Added PKCS12 API and implementation for ...

lucas.fisher at gmail.com lucas.fisher at gmail.com
Sat Apr 16 19:35:55 EDT 2011


----------------------------------------------------------------------
Revision: 3a04ab1fbc926699834c544430efd357ac3edd9e
Parent:   f0759677c057f9a18cef866b59580d4be147801c
Author:   lucas.fisher at gmail.com
Date:     04/16/11 16:11:02
Branch:   im.pidgin.cpw.ljfisher.ssl_client_auth
URL: http://d.pidgin.im/viewmtn/revision/info/3a04ab1fbc926699834c544430efd357ac3edd9e

Changelog: 

Added PKCS12 API and implementation for use with SSL/TLS client side certificate authentication.

Changes against parent f0759677c057f9a18cef866b59580d4be147801c

  added    libpurple/pkcs12.c
  added    libpurple/pkcs12.h

-------------- next part --------------
============================================================
--- /dev/null	
+++ libpurple/pkcs12.c	3973cbae39543e5119e29f597db46f71f18aa17e
@@ -0,0 +1,209 @@
+/**
+ * @file pkcs12.c PKCS12 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 "internal.h"
+#include "pkcs12.h"
+#include "dbus-maybe.h"
+#include "debug.h"
+#include "request.h"
+#include "signals.h"
+#include "util.h"
+
+/** List holding pointers to all registered private key schemes */
+static GList *pkcs12_schemes = NULL;
+
+gboolean
+purple_pkcs12_import(PurplePkcs12Scheme *scheme, const gchar *filename, const gchar *password,
+					 PurpleCertificate **crt, PurplePrivateKey **key)
+{
+	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(crt, FALSE);
+	g_return_val_if_fail(key, FALSE);
+
+	return (scheme->import_pkcs12)(filename, password, crt, key);
+}
+
+gboolean
+purple_pkcs12_export(PurplePkcs12Scheme *scheme, const gchar *filename, const gchar *password,
+					 PurpleCertificate *crt, PurplePrivateKey *key)
+{
+	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(crt, FALSE);
+	g_return_val_if_fail(key, FALSE);
+
+	return (scheme->export_pkcs12)(filename, password, crt, key);
+}
+
+gboolean
+purple_pkcs12_import_to_pool(PurplePkcs12Scheme *scheme, const gchar *filename, const gchar *password,
+							 PurpleCertificatePool *certpool, PurplePrivateKeyPool *keypool)
+{
+	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(certpool, FALSE);
+	g_return_val_if_fail(keypool, FALSE);
+
+	return FALSE;
+}
+
+void
+purple_pkcs12_request_password(void* handle, const char* filename, GCallback ok_cb,
+				GCallback cancel_cb, void *user_data)
+{
+	gchar *primary;
+	PurpleRequestFieldGroup *group;
+	PurpleRequestField *field;
+	PurpleRequestFields *fields;
+
+	/* Close any previous password request windows */
+	purple_request_close_with_handle((void*)filename);
+
+	/* TODO: Should display only filename and not whole path */
+	primary = g_strdup_printf(_("Enter password for %s"), filename);
+
+	fields = purple_request_fields_new();
+	group = purple_request_field_group_new(NULL);
+	purple_request_fields_add_group(fields, group);
+
+	field = purple_request_field_string_new("password", _("Enter Password"), NULL, FALSE);
+	purple_request_field_string_set_masked(field, TRUE);
+	purple_request_field_set_required(field, TRUE);
+	purple_request_field_group_add_field(group, field);
+/*
+	field = purple_request_field_bool_new("remember", _("Save password"), FALSE);
+	purple_request_field_group_add_field(group, field);
+*/
+	purple_request_fields(handle,              /* handle    */
+                        _("Enter Password"),       /* title     */
+                        primary,                   /* primary   */
+                        NULL,                      /* secondary */
+                        fields,                    /* fields    */
+                        _("OK"), ok_cb,            /* ok text and callback */
+                        _("Cancel"), cancel_cb,    /* cancel text and callback */
+			NULL, NULL, NULL,          /* account, who, conv */
+                        user_data);                /* callback data */
+	g_free(primary); /* TODO: not right */
+}
+
+/****************************************************************************/
+/* Subsystem                                                                */
+/****************************************************************************/
+void
+purple_pkcs12_init(void)
+{
+}
+
+void
+purple_pkcs12_uninit(void)
+{
+}
+
+gpointer
+purple_pkcs12_get_handle(void)
+{
+	static gint handle;
+	return &handle;
+}
+
+PurplePkcs12Scheme *
+purple_pkcs12_find_scheme(const gchar *name)
+{
+	PurplePkcs12Scheme *scheme = NULL;
+	GList *l;
+
+	g_return_val_if_fail(name, NULL);
+
+	/* Traverse the list of registered schemes and locate the
+	   one whose name matches */
+	for(l = pkcs12_schemes; l; l = l->next) {
+		scheme = (PurplePkcs12Scheme *)(l->data);
+
+		/* Name matches? that's our man */
+		if(!g_ascii_strcasecmp(scheme->name, name))
+			return scheme;
+	}
+
+	purple_debug_warning("pkcs12",
+			     "Pkcs12Scheme %s requested but not found.\n",
+			     name);
+
+	/* TODO: Signalling and such? */
+
+	return NULL;
+}
+
+GList *
+purple_pkcs12_get_schemes(void)
+{
+	return pkcs12_schemes;
+}
+
+gboolean
+purple_pkcs12_register_scheme(PurplePkcs12Scheme *scheme)
+{
+	g_return_val_if_fail(scheme != NULL, FALSE);
+
+	/* Make sure no scheme is registered with the same name */
+	if (purple_pkcs12_find_scheme(scheme->name) != NULL) {
+		return FALSE;
+	}
+
+	/* Okay, we're golden. Register it. */
+	pkcs12_schemes = g_list_prepend(pkcs12_schemes, scheme);
+
+	/* TODO: Signalling and such? */
+
+	purple_debug_info("pkcs12",
+			  "Pkcs12Scheme %s registered\n",
+			  scheme->name);
+
+	return TRUE;
+}
+
+gboolean
+purple_pkcs12_unregister_scheme(PurplePkcs12Scheme *scheme)
+{
+	if (NULL == scheme) {
+		purple_debug_warning("pkcs12",
+				     "Attempting to unregister NULL scheme\n");
+		return FALSE;
+	}
+
+	pkcs12_schemes = g_list_remove(pkcs12_schemes, scheme);
+
+	purple_debug_info("pkcs12",
+			  "Pkcs12Scheme %s unregistered\n",
+			  scheme->name);
+
+	return TRUE;
+}
============================================================
--- /dev/null	
+++ libpurple/pkcs12.h	05d4a10d6c746924f33988bcc583483496e0cc8b
@@ -0,0 +1,226 @@
+/**
+ * @file pkcs12.h PKCS12 API
+ * @ingroup core
+ * @see 
+ * @since 2.2.0
+ */
+
+/*
+ *
+ * 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_PKCS12_H
+#define _PURPLE_PKCS12_H
+
+#include <time.h>
+
+#include <glib.h>
+
+#include <pkcs12.h>
+#include <certificate.h>
+#include <privatekey.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _PurplePkcs12Scheme PurplePkcs12Scheme;
+
+/** PKCS12 import/export
+ *
+ *  A Pkcs12Scheme must implement all of the fields in the structure,
+ *  and register it using purple_pkcs12_register_scheme()
+ */
+struct _PurplePkcs12Scheme
+{
+	/** Name of the pkcs12 scheme
+	 *  ex: "pkcs12"
+	 *  This must be globally unique - you may not register more than one
+	 *  Pkcs12Scheme of the same name at a time.
+	 */
+	gchar * name;
+
+	/** User-friendly name for this type
+	 *  ex: N_("X.509 PKCS12")
+	 *  When this is displayed anywhere, it should be i18ned
+	 *  ex: _(scheme->fullname)
+	 */
+	gchar * fullname;
+
+	/**
+	* Imports PurpleCertificates and PurplePrivateKeys from a PKCS12 file
+	*
+	* @param filename    File path to import from
+	* @param password    Password protecting the PKCS12 file
+	* @param crt         Certificate in the PKCS12 file. Must be free'd by caller.
+	* @param key         Private key in the PKCS12 file. Must be free'd by caller.
+	* @return TRUE if at least one certificate and key were imported, and FALSE on failure
+	*/
+	gboolean (*import_pkcs12)(const gchar *filename, const gchar *password,
+				  PurpleCertificate **crt, PurplePrivateKey **key);
+
+	/**
+	* Exports PurpleCertificates and PurplePrivateKey to a file
+	*
+	* @param filename    File to export the key to
+	* @param password    Password to protect the PKCS12 file
+	* @param crt         Certificate to export
+	* @param key         Key to export
+	* @return TRUE if the export succeeded, otherwise FALSE
+	*/
+	gboolean (*export_pkcs12)(const gchar *filename, const gchar *password,
+				  PurpleCertificate *crt, PurplePrivateKey *key);
+
+	void (*_purple_reserved1)(void);
+	void (*_purple_reserved2)(void);
+	void (*_purple_reserved3)(void);
+};
+
+/*@}*/
+
+/*****************************************************************************/
+/** @name PKCS12 Functions                                              */
+/*****************************************************************************/
+/*@{*/
+
+/**
+ * Imports PurpleCertificates and PurplePrivateKeys from a PKCS12 file
+ *
+ * @param scheme      Scheme to import under
+ * @param filename    File path to import from
+ * @param password    Password protecting the PKCS12 file
+ * @param crt         Certificate in the PKCS12 file. Must be free'd by caller.
+ * @param key         Private key in the PKCS12 file. Must be free'd by caller.
+ * @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,
+					 PurpleCertificate **crt, PurplePrivateKey **key);
+
+/**
+ * Exports PurpleCertificates and PurplePrivateKey to a file
+ *
+ * @param filename    File to export the key to
+ * @param password    Password to protect the PKCS12 file
+ * @param crt         Certificate to export
+ * @param key         Key to export
+ * @return TRUE if the export succeeded, otherwise FALSE
+ */
+gboolean
+purple_pkcs12_export(PurplePkcs12Scheme *scheme, const gchar *filename, const gchar *password,
+					 PurpleCertificate *crt, PurplePrivateKey *key);
+
+/**
+ * Imports certificates and key into given certificate and private key pools.
+ * 
+ * @param scheme      Scheme to import under
+ * @param filename    File path to import from
+ * @param password    Password protecting the PKCS12 file
+ * @param certpool    CertificatePool to import certificates into
+ * @param keypool     PrivateKeyPool to import keys into
+ * @return TRUE if as least one certificate and key were imported, and FALSE on failure
+ */
+gboolean
+purple_pkcs12_import_to_pool(PurplePkcs12Scheme *scheme, const gchar *filename, const gchar *password,
+							 PurpleCertificatePool *certpool, PurplePrivateKeyPool *keypool);
+
+/**
+ * Request the password used to encrypt the pkcs12 file.
+ *
+ * @param filename File name of the pkcs12 file.
+ * @param ok_cb  Called when the user acknowledges the request.
+ * @param cancel_cb Called when the user cancels the request.
+ * @param user_data Opaque data pointer.
+ */
+void
+purple_pkcs12_request_password(void* handle, const char* filename, GCallback ok_cb,
+				GCallback cancel_cb, void *user_data);
+/*@}*/
+
+/*****************************************************************************/
+/** @name PKCS12 Subsystem API                                               */
+/*****************************************************************************/
+/*@{*/
+
+/**
+ * Initialize the PKCS12 system
+ */
+void
+purple_pkcs12_init(void);
+
+/**
+ * Un-initialize the pkcs12 system
+ */
+void
+purple_pkcs12_uninit(void);
+
+/**
+ * Get the pkcs12 subsystem handle for signalling purposes
+ */
+gpointer
+purple_pkcs12_get_handle(void);
+
+/** Look up a registered PKCS12 by name
+ * @param name   The scheme name. Case insensitive.
+ * @return Pointer to the located Scheme, or NULL if it isn't found.
+ */
+PurplePkcs12Scheme *
+purple_pkcs12_find_scheme(const gchar *name);
+
+/**
+ * Get all registered Pkcs12Schemes
+ *
+ * @return GList pointing to all registered Pkcs12Schemes . This value
+ *         is owned by libpurple
+ */
+GList *
+purple_pkcs12_get_schemes(void);
+
+/** Register a Pkcs12Scheme with libpurple
+ *
+ * No two schemes can be registered with the same name; this function enforces
+ * that.
+ *
+ * @param scheme  Pointer to the scheme to register.
+ * @return TRUE if the scheme was successfully added, otherwise FALSE
+ */
+gboolean
+purple_pkcs12_register_scheme(PurplePkcs12Scheme *scheme);
+
+/** Unregister a Pkcs12Scheme from libpurple
+ *
+ * @param scheme    Scheme to unregister.
+ *                  If the scheme is not registered, this is a no-op.
+ *
+ * @return TRUE if the unregister completed successfully
+ */
+gboolean
+purple_pkcs12_unregister_scheme(PurplePkcs12Scheme *scheme);
+
+/*@}*/
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _PURPLE_PKCS12_H */


More information about the Commits mailing list