/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