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