/soc/2013/ankitkv/gobjectification: 9a96150a0365: GObjectified t...

Ankit Vani a at nevitus.org
Fri Jun 14 05:58:02 EDT 2013


Changeset: 9a96150a0365aaefb82e0256753fd3622ceb9be8
Author:	 Ankit Vani <a at nevitus.org>
Date:	 2013-06-14 15:27 +0530
Branch:	 soc.2013.gobjectification
URL: https://hg.pidgin.im/soc/2013/ankitkv/gobjectification/rev/9a96150a0365

Description:

GObjectified the HMAC cipher as PurpleHMACCipher

diffstat:

 libpurple/ciphers/hmac.c |  498 ++++++++++++++++++++++++++++------------------
 libpurple/ciphers/hmac.h |   71 ++++++
 2 files changed, 368 insertions(+), 201 deletions(-)

diffs (truncated from 606 to 300 lines):

diff --git a/libpurple/ciphers/hmac.c b/libpurple/ciphers/hmac.c
--- a/libpurple/ciphers/hmac.c
+++ b/libpurple/ciphers/hmac.c
@@ -19,229 +19,325 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
+#include "hmac.h"
 
-#include "internal.h"
-#include <cipher.h>
-#include "ciphers.h"
+#include <string.h>
 
-#include <util.h>
+/*******************************************************************************
+ * Structs
+ ******************************************************************************/
+#define PURPLE_HMAC_CIPHER_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_HMAC_CIPHER, PurpleHMACCipherPrivate))
 
-struct HMAC_Context {
-	PurpleCipherContext *hash;
-	char *name;
-	int blocksize;
-	guchar *opad, *ipad;
+typedef struct {
+	PurpleCipher *hash;
+	guchar *ipad;
+	guchar *opad;
+} PurpleHMACCipherPrivate;
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+	PROP_NONE,
+	PROP_HASH,
+	PROP_LAST,
 };
 
-	static void
-hmac_init(PurpleCipherContext *context, gpointer extra)
+/*******************************************************************************
+ * Globals
+ ******************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/*******************************************************************************
+ * Helpers
+ ******************************************************************************/
+static void
+purple_hmac_cipher_set_hash(PurpleCipher *cipher,
+							PurpleCipher *hash)
 {
-	struct HMAC_Context *hctx;
-	hctx = g_new0(struct HMAC_Context, 1);
-	purple_cipher_context_set_data(context, hctx);
-	purple_cipher_context_reset(context, extra);
+	PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+	priv->hash = g_object_ref(G_OBJECT(hash));
 }
 
-	static void
-hmac_reset(PurpleCipherContext *context, gpointer extra)
-{
-	struct HMAC_Context *hctx;
+/*******************************************************************************
+ * Cipher Stuff
+ ******************************************************************************/
+static void
+purple_hmac_cipher_reset(PurpleCipher *cipher) {
+	PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
 
-	hctx = purple_cipher_context_get_data(context);
+	if(PURPLE_IS_CIPHER(priv->hash))
+		purple_cipher_reset(priv->hash);
 
-	g_free(hctx->name);
-	hctx->name = NULL;
-	if (hctx->hash)
-		purple_cipher_context_destroy(hctx->hash);
-	hctx->hash = NULL;
-	hctx->blocksize = 0;
-	g_free(hctx->opad);
-	hctx->opad = NULL;
-	g_free(hctx->ipad);
-	hctx->ipad = NULL;
-}
-
-	static void
-hmac_reset_state(PurpleCipherContext *context, gpointer extra)
-{
-	struct HMAC_Context *hctx;
-
-	hctx = purple_cipher_context_get_data(context);
-
-	if (hctx->hash) {
-		purple_cipher_context_reset_state(hctx->hash, NULL);
-		purple_cipher_context_append(hctx->hash, hctx->ipad, hctx->blocksize);
+	if(priv->ipad) {
+		g_free(priv->ipad);
+		priv->ipad = NULL;
+	}
+	if(priv->opad) {
+		g_free(priv->opad);
+		priv->opad = NULL;
 	}
 }
 
-	static void
-hmac_set_opt(PurpleCipherContext *context, const gchar *name, void *value)
-{
-	struct HMAC_Context *hctx;
+static void
+purple_hmac_cipher_reset_state(PurpleCipher *cipher) {
+	PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
 
-	hctx = purple_cipher_context_get_data(context);
-
-	if (purple_strequal(name, "hash")) {
-		g_free(hctx->name);
-		if (hctx->hash)
-			purple_cipher_context_destroy(hctx->hash);
-		hctx->name = g_strdup((char*)value);
-		hctx->hash = purple_cipher_context_new_by_name((char *)value, NULL);
-		hctx->blocksize = purple_cipher_context_get_block_size(hctx->hash);
+	if(PURPLE_IS_CIPHER(priv->hash)) {
+		purple_cipher_reset_state(priv->hash);
+		purple_cipher_append(priv->hash, priv->ipad,
+								purple_cipher_get_block_size(priv->hash));
 	}
 }
 
-	static void *
-hmac_get_opt(PurpleCipherContext *context, const gchar *name)
+static void
+purple_hmac_cipher_set_iv(PurpleCipher *cipher, guchar *iv, size_t len) {
+	PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+	if(PURPLE_IS_CIPHER(priv->hash))
+		purple_cipher_set_iv(priv->hash, iv, len);
+}
+
+static void
+purple_hmac_cipher_append(PurpleCipher *cipher, const guchar *d, size_t l) {
+	PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+	g_return_if_fail(PURPLE_IS_CIPHER(priv->hash));
+
+	purple_cipher_append(priv->hash, d, l);
+}
+
+static gboolean
+purple_hmac_cipher_digest(PurpleCipher *cipher, guchar *out, size_t len)
 {
-	struct HMAC_Context *hctx;
+	PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+	guchar *digest = NULL;
+	size_t hash_len, block_size;
+	gboolean result = FALSE;
 
-	hctx = purple_cipher_context_get_data(context);
+	g_return_val_if_fail(PURPLE_IS_CIPHER(priv->hash), FALSE);
 
-	if (purple_strequal(name, "hash")) {
-		return hctx->name;
+	hash_len = purple_cipher_get_digest_size(priv->hash);
+	g_return_val_if_fail(hash_len > 0, FALSE);
+
+	block_size = purple_cipher_get_block_size(priv->hash);
+	digest = g_malloc(hash_len);
+
+	/* get the digest of the data */
+	result = purple_cipher_digest(priv->hash, digest, hash_len);
+	purple_cipher_reset(priv->hash);
+
+	if(!result) {
+		g_free(digest);
+
+		return FALSE;
 	}
 
+	/* now append the opad and the digest from above */
+	purple_cipher_append(priv->hash, priv->opad, block_size);
+	purple_cipher_append(priv->hash, digest, hash_len);
+
+	/* do our last digest */
+	result = purple_cipher_digest(priv->hash, out, len);
+
+	/* cleanup */
+	g_free(digest);
+
+	return result;
+}
+
+static size_t
+purple_hmac_cipher_get_digest_size(PurpleCipher *cipher)
+{
+	PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+	g_return_val_if_fail(priv->hash != NULL, 0);
+
+	return purple_cipher_get_digest_size(priv->hash);
+}
+
+static void
+purple_hmac_cipher_set_key(PurpleCipher *cipher, const guchar *key,
+								size_t key_len)
+{
+	PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+	gint block_size, i;
+	guchar *full_key;
+
+	g_return_if_fail(priv->hash);
+
+	g_free(priv->ipad);
+	g_free(priv->opad);
+
+	block_size = purple_cipher_get_block_size(priv->hash);
+	priv->ipad = g_malloc(block_size);
+	priv->opad = g_malloc(block_size);
+
+	if (key_len > block_size) {
+		purple_cipher_reset(priv->hash);
+		purple_cipher_append(priv->hash, key, key_len);
+
+		key_len = purple_cipher_get_digest_size(priv->hash);
+		full_key = g_malloc(key_len);
+		purple_cipher_digest(priv->hash, full_key, key_len);
+	} else {
+		full_key = g_memdup(key, key_len);
+	}
+
+    if (key_len < block_size) {
+		full_key = g_realloc(full_key, block_size);
+		memset(full_key + key_len, 0, block_size - key_len);
+    }
+
+	for(i = 0; i < block_size; i++) {
+		priv->ipad[i] = 0x36 ^ full_key[i];
+		priv->opad[i] = 0x5c ^ full_key[i];
+	}
+
+	g_free(full_key);
+
+	purple_cipher_reset(priv->hash);
+	purple_cipher_append(priv->hash, priv->ipad, block_size);
+}
+
+static size_t
+purple_hmac_cipher_get_block_size(PurpleCipher *cipher)
+{
+	PurpleHMACCipherPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_HMAC_CIPHER(cipher), 0);
+
+	priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher);
+
+	return purple_hmac_cipher_get_block_size(priv->hash);
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_hmac_cipher_set_property(GObject *obj, guint param_id,
+								const GValue *value,
+								GParamSpec *pspec)
+{
+	PurpleCipher *cipher = PURPLE_CIPHER(obj);
+
+	switch(param_id) {
+		case PROP_HASH:
+			purple_hmac_cipher_set_hash(cipher, g_value_get_object(value));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+
+static void
+purple_hmac_cipher_get_property(GObject *obj, guint param_id, GValue *value,
+								GParamSpec *pspec)
+{
+	PurpleHMACCipher *cipher = PURPLE_HMAC_CIPHER(obj);
+
+	switch(param_id) {
+		case PROP_HASH:
+			g_value_set_object(value,
+							   purple_hmac_cipher_get_hash(cipher));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+



More information about the Commits mailing list