gobjectification: 760fcafe: Patch from xanderw to have some more ciâ¦
sadrul at pidgin.im
sadrul at pidgin.im
Sat Mar 1 04:56:45 EST 2008
-----------------------------------------------------------------
Revision: 760fcafe15614b682f788c4d95abe462277ed964
Ancestor: 4744a54253d61080c6199372f133da2bc93254b8
Author: sadrul at pidgin.im
Date: 2008-03-01T09:52:34
Branch: im.pidgin.gobjectification
URL: http://d.pidgin.im/viewmtn/revision/info/760fcafe15614b682f788c4d95abe462277ed964
Added files:
libpurple/des3cipher.c libpurple/des3cipher.h
libpurple/hmaccipher.c libpurple/hmaccipher.h
libpurple/rc4cipher.c libpurple/rc4cipher.h
ChangeLog:
Patch from xanderw to have some more cipher stuff. References #35.
-------------- next part --------------
============================================================
--- libpurple/des3cipher.c 2dc0bfbbca01cb63e18a33b8e6e9016b5d2a0ad4
+++ libpurple/des3cipher.c 2dc0bfbbca01cb63e18a33b8e6e9016b5d2a0ad4
@@ -0,0 +1,468 @@
+/*
+ * 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 "des3cipher.h"
+#include "descipher.h"
+
+#include <string.h>
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+struct _PurpleDES3CipherPriv
+{
+ PurpleCipherBatchMode mode;
+ guchar iv[8];
+ /* First key for encryption */
+ PurpleCipher *key1;
+ /* Second key for decryption */
+ PurpleCipher *key2;
+ /* Third key for encryption */
+ PurpleCipher *key3;
+};
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_NONE,
+ PROP_BATCH_MODE,
+ PROP_IV,
+ PROP_KEY,
+ PROP_LAST,
+};
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/******************************************************************************
+ * Cipher Stuff
+ *****************************************************************************/
+/*
+ * Fill a DES3 context with subkeys calculated from 3 64bit key.
+ * Does not check parity bits, but simply ignore them.
+ * Does not check for weak keys.
+ **/
+static void
+purple_des3_cipher_set_key(PurpleCipher *cipher, const guchar * key)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+
+ purple_cipher_set_key(PURPLE_CIPHER(des3_cipher->priv->key1), key + 0);
+ purple_cipher_set_key(PURPLE_CIPHER(des3_cipher->priv->key2), key + 8);
+ purple_cipher_set_key(PURPLE_CIPHER(des3_cipher->priv->key3), key + 16);
+
+ g_object_notify(G_OBJECT(des3_cipher), "key");
+}
+
+static gint
+purple_des3_cipher_ecb_encrypt(PurpleDES3Cipher *des3_cipher, const guchar data[],
+ size_t len, guchar output[], size_t *outlen)
+{
+ int offset = 0;
+ int i = 0;
+ int tmp;
+ guint8 buf[8] = {0,0,0,0,0,0,0,0};
+
+ while (offset + 8 <= len) {
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key1),
+ data + offset, output + offset, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key2),
+ output + offset, buf, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key3),
+ buf, output + offset, 0);
+
+ offset += 8;
+ }
+
+ *outlen = len;
+
+ if (offset < len) {
+ *outlen += len - offset;
+ tmp = offset;
+ memset(buf, 0, 8);
+
+ while (tmp < len) {
+ buf[i++] = data[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key1),
+ buf, output + offset, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key2),
+ output + offset, buf, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key3),
+ buf, output + offset, 0);
+ }
+
+ return 0;
+}
+
+static gint
+purple_des3_cipher_cbc_encrypt(PurpleDES3Cipher *des3_cipher, const guchar data[],
+ size_t len, guchar output[], size_t *outlen)
+{
+ int offset = 0;
+ int i = 0;
+ int tmp;
+ guint8 buf[8];
+
+ memcpy(buf, des3_cipher->priv->iv, 8);
+
+ while (offset + 8 <= len) {
+ for (i = 0; i < 8; i++)
+ buf[i] ^= data[offset + i];
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key1),
+ buf, output + offset, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key2),
+ output + offset, buf, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key3),
+ buf, output + offset, 0);
+
+ memcpy(buf, output+offset, 8);
+ offset += 8;
+ }
+
+ *outlen = len;
+
+ if (offset < len) {
+ *outlen += len - offset;
+ tmp = offset;
+ i = 0;
+
+ while (tmp < len) {
+ buf[i++] ^= data[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key1),
+ buf, output + offset, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key2),
+ output + offset, buf, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key3),
+ buf, output + offset, 0);
+ }
+
+ return 0;
+}
+
+static gint
+purple_des3_cipher_encrypt(PurpleCipher *cipher, const guchar data[],
+ size_t len, guchar output[], size_t *outlen)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+
+ if (des3_cipher->priv->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
+ return purple_des3_cipher_ecb_encrypt(des3_cipher, data, len, output, outlen);
+ } else if (des3_cipher->priv->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
+ return purple_des3_cipher_cbc_encrypt(des3_cipher, data, len, output, outlen);
+ } else {
+ g_return_val_if_reached(0);
+ }
+
+ return 0;
+}
+
+static gint
+purple_des3_cipher_ecb_decrypt(PurpleDES3Cipher *des3_cipher, const guchar data[],
+ size_t len, guchar output[], size_t *outlen)
+{
+ int offset = 0;
+ int i = 0;
+ int tmp;
+ guint8 buf[8] = {0,0,0,0,0,0,0,0};
+
+ while (offset + 8 <= len) {
+ /* NOTE: Apply key in reverse */
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key3),
+ data + offset, output + offset, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key2),
+ output + offset, buf, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key1),
+ buf, output + offset, 1);
+
+ offset += 8;
+ }
+
+ *outlen = len;
+
+ if (offset < len) {
+ *outlen += len - offset;
+ tmp = offset;
+ memset(buf, 0, 8);
+
+ while (tmp < len) {
+ buf[i++] = data[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key3),
+ buf, output + offset, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key2),
+ output + offset, buf, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key1),
+ buf, output + offset, 1);
+ }
+
+ return 0;
+}
+
+static gint
+purple_des3_cipher_cbc_decrypt(PurpleDES3Cipher *des3_cipher, const guchar data[],
+ size_t len, guchar output[], size_t *outlen)
+{
+ int offset = 0;
+ int i = 0;
+ int tmp;
+ guint8 buf[8] = {0,0,0,0,0,0,0,0};
+ guint8 link[8];
+
+ memcpy(link, des3_cipher->priv->iv, 8);
+
+ while (offset + 8 <= len) {
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key3),
+ data + offset, output + offset, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key2),
+ output + offset, buf, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key1),
+ buf, output + offset, 1);
+
+ for (i = 0; i < 8; i++)
+ output[offset + i] ^= link[i];
+
+ memcpy(link, data + offset, 8);
+
+ offset+=8;
+ }
+
+ *outlen = len;
+
+ if(offset<len) {
+ *outlen += len - offset;
+ tmp = offset;
+ memset(buf, 0, 8);
+ i = 0;
+
+ while(tmp<len) {
+ buf[i++] = data[tmp];
+ tmp++;
+ }
+
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key3),
+ buf, output + offset, 1);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key2),
+ output + offset, buf, 0);
+ purple_des_cipher_ecb_crypt(PURPLE_DES_CIPHER(des3_cipher->priv->key1),
+ buf, output + offset, 1);
+
+ for (i = 0; i < 8; i++)
+ output[offset + i] ^= link[i];
+ }
+
+ return 0;
+}
+
+static gint
+purple_des3_cipher_decrypt(PurpleCipher *cipher, const guchar data[],
+ size_t len, guchar output[], size_t *outlen)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+
+ if (des3_cipher->priv->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
+ return purple_des3_cipher_ecb_decrypt(des3_cipher, data, len, output, outlen);
+ } else if (des3_cipher->priv->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
+ return purple_des3_cipher_cbc_decrypt(des3_cipher, data, len, output, outlen);
+ } else {
+ g_return_val_if_reached(0);
+ }
+
+ return 0;
+}
+
+static void
+purple_des3_cipher_set_batch_mode(PurpleCipher *cipher, PurpleCipherBatchMode mode)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+
+ des3_cipher->priv->mode = mode;
+
+ g_object_notify(G_OBJECT(des3_cipher), "batchMode");
+}
+
+static PurpleCipherBatchMode
+purple_des3_cipher_get_batch_mode(PurpleCipher *cipher)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+
+ return des3_cipher->priv->mode;
+}
+
+static void
+purple_des3_cipher_set_iv(PurpleCipher *cipher, guchar *iv, size_t len)
+{
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+
+ g_return_if_fail(len == 8);
+
+ memcpy(des3_cipher->priv->iv, iv, len);
+
+ g_object_notify(G_OBJECT(des3_cipher), "iv");
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_des3_cipher_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_BATCH_MODE:
+ g_value_set_enum(value,
+ purple_cipher_get_batch_mode(cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_des3_cipher_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+ guchar *iv;
+
+ switch(param_id) {
+ case PROP_BATCH_MODE:
+ purple_cipher_set_batch_mode(cipher,
+ g_value_get_enum(value));
+ break;
+ case PROP_IV:
+#warning I really dont like this...
+ iv = (guchar *)g_value_get_string(value);
+ purple_cipher_set_iv(cipher, iv, strlen((gchar*)iv));
+ break;
+ case PROP_KEY:
+ purple_cipher_set_key(cipher, (guchar *)g_value_get_string(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_des3_cipher_finalize(GObject *obj) {
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(obj);
+
+ g_object_unref(G_OBJECT(des3_cipher->priv->key1));
+ g_object_unref(G_OBJECT(des3_cipher->priv->key2));
+ g_object_unref(G_OBJECT(des3_cipher->priv->key3));
+
+ memset(des3_cipher->priv->iv, 0, sizeof(des3_cipher->priv->iv));
+
+ g_free(des3_cipher->priv);
+}
+
+static void
+purple_des3_cipher_class_init(PurpleDES3CipherClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
+ GParamSpec *pspec;
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->finalize = purple_des3_cipher_finalize;
+ obj_class->get_property = purple_des3_cipher_get_property;
+ obj_class->set_property = purple_des3_cipher_set_property;
+
+ cipher_class->set_iv = purple_des3_cipher_set_iv;
+ cipher_class->encrypt = purple_des3_cipher_encrypt;
+ cipher_class->decrypt = purple_des3_cipher_decrypt;
+ cipher_class->set_key = purple_des3_cipher_set_key;
+ cipher_class->set_batch_mode = purple_des3_cipher_set_batch_mode;
+ cipher_class->get_batch_mode = purple_des3_cipher_get_batch_mode;
+
+ pspec = g_param_spec_enum("batchMode", "batchMode", "batchMode",
+ PURPLE_TYPE_CIPHER_BATCH_MODE, 0,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(obj_class, PROP_BATCH_MODE, pspec);
+
+ pspec = g_param_spec_string("iv", "iv", "iv", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_IV, pspec);
+
+ pspec = g_param_spec_string("key", "key", "key", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_KEY, pspec);
+}
+
+static void
+purple_des3_cipher_init(PurpleCipher *cipher) {
+ PurpleDES3Cipher *des3_cipher = PURPLE_DES3_CIPHER(cipher);
+
+ des3_cipher->priv = g_new0(PurpleDES3CipherPriv, 1);
+
+ des3_cipher->priv->key1 = purple_des_cipher_new();
+ des3_cipher->priv->key2 = purple_des_cipher_new();
+ des3_cipher->priv->key3 = purple_des_cipher_new();
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_des3_cipher_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleDES3CipherClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_des3_cipher_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleDES3Cipher),
+ 0,
+ (GInstanceInitFunc)purple_des3_cipher_init,
+ NULL
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CIPHER,
+ "PurpleDES3Cipher",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleCipher *
+purple_des3_cipher_new(void) {
+ return g_object_new(PURPLE_TYPE_DES3_CIPHER, NULL);
+}
============================================================
--- libpurple/des3cipher.h 1cf98e02bab972f08aceb15845f8509861befe74
+++ libpurple/des3cipher.h 1cf98e02bab972f08aceb15845f8509861befe74
@@ -0,0 +1,71 @@
+/**
+ * @file des3cipher.h Purple Triple-DES Cipher
+ * @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
+ */
+#ifndef PURPLE_DES3_CIPHER_H
+#define PURPLE_DES3_CIPHER_H
+
+#include <cipher.h>
+
+#define PURPLE_TYPE_DES3_CIPHER (purple_des3_cipher_get_gtype())
+#define PURPLE_DES3_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_DES3_CIPHER, PurpleDES3Cipher))
+#define PURPLE_DES3_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_DES3_CIPHER, PurpleDES3CipherClass))
+#define PURPLE_IS_DES3_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_DES3_CIPHER))
+#define PURPLE_IS_DES3_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_DES3_CIPHER))
+#define PURPLE_DES3_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_DES3_CIPHER, PurpleDES3CipherClass))
+
+typedef struct _PurpleDES3Cipher PurpleDES3Cipher;
+typedef struct _PurpleDES3CipherPriv PurpleDES3CipherPriv;
+typedef struct _PurpleDES3CipherClass PurpleDES3CipherClass;
+
+struct _PurpleDES3Cipher {
+ PurpleCipher gparent;
+
+ PurpleDES3CipherPriv *priv;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+struct _PurpleDES3CipherClass {
+ PurpleCipherClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_des3_cipher_get_gtype(void);
+
+PurpleCipher *purple_des3_cipher_new(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_DES3_CIPHER_H */
+
============================================================
--- libpurple/hmaccipher.c 44ad9ef92f1f5abf7187c21d1881cc490986de28
+++ libpurple/hmaccipher.c 44ad9ef92f1f5abf7187c21d1881cc490986de28
@@ -0,0 +1,319 @@
+/*
+ * 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 "hmaccipher.h"
+
+#include <string.h>
+
+/*******************************************************************************
+ * Structs
+ ******************************************************************************/
+struct _PurpleHMACCipherPriv {
+ PurpleCipher *hash;
+ int blocksize;
+ guchar *opad;
+};
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_NONE,
+ PROP_BLOCK_SIZE,
+ PROP_HASH,
+ PROP_KEY,
+ PROP_LAST,
+};
+
+/*******************************************************************************
+ * Globals
+ ******************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/*******************************************************************************
+ * Cipher Stuff
+ ******************************************************************************/
+static void
+purple_hmac_cipher_reset(PurpleCipher *cipher)
+{
+ PurpleHMACCipher *hmac_cipher = PURPLE_HMAC_CIPHER(cipher);
+
+ if(hmac_cipher->priv->hash)
+ {
+ g_object_unref(G_OBJECT(hmac_cipher->priv->hash));
+ hmac_cipher->priv->hash = NULL;
+ }
+
+ hmac_cipher->priv->blocksize = 0;
+
+ if(hmac_cipher->priv->opad)
+ {
+ g_free(hmac_cipher->priv->opad);
+ hmac_cipher->priv->opad = NULL;
+ }
+}
+
+static void
+purple_hmac_cipher_append(PurpleCipher *cipher, const guchar *data, size_t len)
+{
+ PurpleHMACCipher *hmac_cipher = PURPLE_HMAC_CIPHER(cipher);
+
+ g_return_if_fail(hmac_cipher->priv->hash);
+
+ purple_cipher_append(hmac_cipher->priv->hash, data, len);
+}
+
+static gboolean
+purple_hmac_cipher_digest(PurpleCipher *cipher, size_t in_len, guchar *out, size_t *out_len)
+{
+ PurpleHMACCipher *hmac_cipher = PURPLE_HMAC_CIPHER(cipher);
+ PurpleCipher *hash = hmac_cipher->priv->hash;
+ guchar *inner_hash;
+ size_t hash_len;
+ gboolean result;
+
+ g_return_val_if_fail(hash, FALSE);
+
+ inner_hash = g_malloc(100); /* TODO: Should be enough for now... */
+ result = purple_cipher_digest(hash, 100, inner_hash, &hash_len);
+
+ purple_cipher_reset(hash);
+
+ purple_cipher_append(hash, hmac_cipher->priv->opad, hmac_cipher->priv->blocksize);
+ purple_cipher_append(hash, inner_hash, hash_len);
+
+ g_free(inner_hash);
+
+ result = result && purple_cipher_digest(hash, in_len, out, out_len);
+
+ return result;
+}
+
+static void
+purple_hmac_cipher_set_key_with_len(PurpleCipher *cipher, const guchar * key, size_t key_len)
+{
+ PurpleHMACCipher *hmac_cipher = PURPLE_HMAC_CIPHER(cipher);
+ int blocksize, i;
+ guchar *ipad;
+ guchar *full_key;
+
+ g_return_if_fail(hmac_cipher->priv->hash);
+
+ g_free(hmac_cipher->priv->opad);
+
+ blocksize = hmac_cipher->priv->blocksize;
+ ipad = g_malloc(blocksize);
+ hmac_cipher->priv->opad = g_malloc(blocksize);
+
+ if (key_len > blocksize) {
+ purple_cipher_reset(hmac_cipher->priv->hash);
+ purple_cipher_append(hmac_cipher->priv->hash, key, key_len);
+ full_key = g_malloc(100); /* TODO: Should be enough for now... */
+ purple_cipher_digest(hmac_cipher->priv->hash, 100, full_key, &key_len);
+ } else
+ full_key = g_memdup(key, key_len);
+
+ if (key_len < blocksize) {
+ full_key = g_realloc(full_key, blocksize);
+ memset(full_key + key_len, 0, blocksize - key_len);
+ }
+
+ for(i = 0; i < blocksize; i++) {
+ ipad[i] = 0x36 ^ full_key[i];
+ hmac_cipher->priv->opad[i] = 0x5c ^ full_key[i];
+ }
+
+ g_free(full_key);
+
+ purple_cipher_reset(hmac_cipher->priv->hash);
+ purple_cipher_append(hmac_cipher->priv->hash, ipad, blocksize);
+ g_free(ipad);
+
+ g_object_notify(G_OBJECT(hmac_cipher), "key");
+}
+
+static void
+purple_hmac_cipher_set_key(PurpleCipher *cipher, const guchar *key)
+{
+ purple_hmac_cipher_set_key_with_len(cipher, key, strlen((char *)key));
+}
+
+static size_t
+purple_hmac_cipher_get_block_size(PurpleCipher *cipher)
+{
+ PurpleHMACCipher *hmac_cipher = PURPLE_HMAC_CIPHER(cipher);
+
+ return hmac_cipher->priv->blocksize;
+}
+
+static void
+purple_hmac_cipher_set_hash(PurpleCipher *cipher,
+ PurpleCipher *hash)
+{
+ PurpleHMACCipher *hmac_cipher = PURPLE_HMAC_CIPHER(cipher);
+
+ hmac_cipher->priv->hash = g_object_ref_sink(hash);
+ hmac_cipher->priv->blocksize = purple_cipher_get_block_size(hash);
+
+ g_object_notify(G_OBJECT(hmac_cipher), "hash");
+}
+
+static PurpleCipher *
+purple_hmac_cipher_get_hash(PurpleCipher *cipher)
+{
+ PurpleHMACCipher *hmac_cipher = PURPLE_HMAC_CIPHER(cipher);
+
+ return hmac_cipher->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_cipher_set_hash(cipher, g_value_get_object(value));
+ break;
+ case PROP_KEY:
+ purple_cipher_set_key(cipher, (guchar *)g_value_get_string(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)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_BLOCK_SIZE:
+ g_value_set_int(value,
+ purple_cipher_get_block_size(cipher));
+ break;
+ case PROP_HASH:
+ g_value_set_object(value,
+ purple_cipher_get_hash(cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_hmac_cipher_finalize(GObject *obj) {
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+ PurpleHMACCipher *hmac_cipher = PURPLE_HMAC_CIPHER(obj);
+
+ /* reset the cipher so we don't leave any data around... */
+ purple_hmac_cipher_reset(cipher);
+
+ g_free(hmac_cipher->priv);
+}
+
+static void
+purple_hmac_cipher_class_init(PurpleHMACCipherClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
+ GParamSpec *pspec;
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->finalize = purple_hmac_cipher_finalize;
+ obj_class->get_property = purple_hmac_cipher_get_property;
+ obj_class->set_property = purple_hmac_cipher_set_property;
+
+ cipher_class->reset = purple_hmac_cipher_reset;
+ cipher_class->append = purple_hmac_cipher_append;
+ cipher_class->digest = purple_hmac_cipher_digest;
+
+ cipher_class->set_key = purple_hmac_cipher_set_key;
+ cipher_class->set_key_with_len = purple_hmac_cipher_set_key_with_len;
+ cipher_class->get_block_size = purple_hmac_cipher_get_block_size;
+ cipher_class->set_hash = purple_hmac_cipher_set_hash;
+ cipher_class->get_hash = purple_hmac_cipher_get_hash;
+
+ pspec = g_param_spec_int("blockSize", "blockSize", "blockSize",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_READABLE);
+ g_object_class_install_property(obj_class, PROP_BLOCK_SIZE, pspec);
+
+ pspec = g_param_spec_object("hash", "hash", "hash", PURPLE_TYPE_CIPHER,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(obj_class, PROP_HASH, pspec);
+
+ pspec = g_param_spec_string("key", "key", "key", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_KEY, pspec);
+}
+
+static void
+purple_hmac_cipher_init(PurpleCipher *cipher) {
+ PurpleHMACCipher *hmac_cipher = PURPLE_HMAC_CIPHER(cipher);
+
+ hmac_cipher->priv = g_new0(PurpleHMACCipherPriv, 1);
+
+ purple_hmac_cipher_reset(cipher);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_hmac_cipher_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleHMACCipherClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_hmac_cipher_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleHMACCipher),
+ 0,
+ (GInstanceInitFunc)purple_hmac_cipher_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CIPHER,
+ "PurpleHMACCipher",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleCipher *
+purple_hmac_cipher_new(void) {
+ return g_object_new(PURPLE_TYPE_HMAC_CIPHER, NULL);
+}
============================================================
--- libpurple/hmaccipher.h d298ee6316a0762841c2072d0f3d0d94da99e2d4
+++ libpurple/hmaccipher.h d298ee6316a0762841c2072d0f3d0d94da99e2d4
@@ -0,0 +1,70 @@
+/**
+ * @file hmaccipher.h Purple HMAC Cipher
+ * @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
+ */
+#ifndef PURPLE_HMAC_CIPHER_H
+#define PURPLE_HMAC_CIPHER_H
+
+#include <cipher.h>
+
+#define PURPLE_TYPE_HMAC_CIPHER (purple_hmac_cipher_get_gtype())
+#define PURPLE_HMAC_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_HMAC_CIPHER, PurpleHMACCipher))
+#define PURPLE_HMAC_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_HMAC_CIPHER, PurpleHMACCipherClass))
+#define PURPLE_IS_HMAC_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_HMAC_CIPHER))
+#define PURPLE_IS_HMAC_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_HMAC_CIPHER))
+#define PURPLE_HMAC_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_HMAC_CIPHER, PurpleHMACCipherClass))
+
+typedef struct _PurpleHMACCipher PurpleHMACCipher;
+typedef struct _PurpleHMACCipherPriv PurpleHMACCipherPriv;
+typedef struct _PurpleHMACCipherClass PurpleHMACCipherClass;
+
+struct _PurpleHMACCipher {
+ PurpleCipher gparent;
+
+ PurpleHMACCipherPriv *priv;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+struct _PurpleHMACCipherClass {
+ PurpleCipherClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_hmac_cipher_get_gtype(void);
+
+PurpleCipher *purple_hmac_cipher_new(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_HMAC_CIPHER_H */
============================================================
--- libpurple/rc4cipher.c f24404ddc7191c7948a56016335f87f437af929e
+++ libpurple/rc4cipher.c f24404ddc7191c7948a56016335f87f437af929e
@@ -0,0 +1,269 @@
+/*
+ * 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 "rc4cipher.h"
+
+/*******************************************************************************
+ * Structs
+ ******************************************************************************/
+struct _PurpleRC4CipherPriv {
+ guchar state[256];
+ guchar x;
+ guchar y;
+ gint key_len;
+};
+
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+ PROP_ZERO,
+ PROP_KEY_LEN,
+ PROP_KEY,
+ PROP_LAST,
+};
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
+
+/******************************************************************************
+ * Cipher Stuff
+ *****************************************************************************/
+static void
+purple_rc4_cipher_reset(PurpleCipher *cipher) {
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(cipher);
+ guint i;
+
+ for(i = 0; i < 256; i++)
+ rc4_cipher->priv->state[i] = i;
+ rc4_cipher->priv->x = 0;
+ rc4_cipher->priv->y = 0;
+
+ /* default is 5 bytes (40bit key) */
+ rc4_cipher->priv->key_len = 5;
+}
+
+static void
+purple_rc4_cipher_set_key (PurpleCipher *cipher, const guchar * key) {
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(cipher);
+ guchar *state;
+ guchar temp_swap;
+ guchar x, y;
+ guint i;
+
+ x = 0;
+ y = 0;
+ state = &rc4_cipher->priv->state[0];
+ for(i = 0; i < 256; i++)
+ {
+ y = (key[x] + state[i] + y) % 256;
+ temp_swap = state[i];
+ state[i] = state[y];
+ state[y] = temp_swap;
+ x = (x + 1) % rc4_cipher->priv->key_len;
+ }
+
+ g_object_notify(G_OBJECT(rc4_cipher), "key");
+}
+
+
+static size_t
+purple_rc4_cipher_get_key_size (PurpleCipher *cipher)
+{
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(cipher);
+
+ return rc4_cipher->priv->key_len;
+}
+
+
+static gint
+purple_rc4_cipher_encrypt(PurpleCipher *cipher, const guchar data[], size_t len,
+ guchar output[], size_t *outlen)
+{
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(cipher);
+ guchar temp_swap;
+ guchar x, y, z;
+ guchar *state;
+ guint i;
+
+ x = rc4_cipher->priv->x;
+ y = rc4_cipher->priv->y;
+ state = &rc4_cipher->priv->state[0];
+
+ for(i = 0; i < len; i++)
+ {
+ x = (x + 1) % 256;
+ y = (state[x] + y) % 256;
+ temp_swap = state[x];
+ state[x] = state[y];
+ state[y] = temp_swap;
+ z = state[x] + (state[y]) % 256;
+ output[i] = data[i] ^ state[z];
+ }
+ rc4_cipher->priv->x = x;
+ rc4_cipher->priv->y = y;
+ if(outlen)
+ *outlen = len;
+
+ return 0;
+}
+
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_rc4_cipher_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_KEY_LEN:
+ purple_rc4_cipher_set_key_len(rc4_cipher, g_value_get_int(value));
+ break;
+ case PROP_KEY:
+ purple_cipher_set_key(cipher, (guchar *)g_value_get_string(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_rc4_cipher_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(obj);
+
+ switch(param_id) {
+ case PROP_KEY_LEN:
+ g_value_set_int(value,
+ purple_rc4_cipher_get_key_len(rc4_cipher));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_rc4_cipher_finalize(GObject *obj) {
+ PurpleCipher *cipher = PURPLE_CIPHER(obj);
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(obj);
+
+ /* reset the cipher so we don't leave any data around... */
+ purple_rc4_cipher_reset(cipher);
+
+ g_free(rc4_cipher->priv);
+}
+
+static void
+purple_rc4_cipher_class_init(PurpleRC4CipherClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
+ GParamSpec *pspec = NULL;
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->set_property = purple_rc4_cipher_set_property;
+ obj_class->get_property = purple_rc4_cipher_get_property;
+ obj_class->finalize = purple_rc4_cipher_finalize;
+
+ cipher_class->reset = purple_rc4_cipher_reset;
+ cipher_class->encrypt = purple_rc4_cipher_encrypt;
+ cipher_class->set_key = purple_rc4_cipher_set_key;
+ cipher_class->get_key_size = purple_rc4_cipher_get_key_size;
+
+ pspec = g_param_spec_int("key_len", "key_len", "key_len",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(obj_class, PROP_KEY_LEN, pspec);
+
+ pspec = g_param_spec_string("key", "key", "key", NULL,
+ G_PARAM_WRITABLE);
+ g_object_class_install_property(obj_class, PROP_KEY, pspec);
+}
+
+static void
+purple_rc4_cipher_init(PurpleCipher *cipher) {
+ PurpleRC4Cipher *rc4_cipher = PURPLE_RC4_CIPHER(cipher);
+
+ rc4_cipher->priv = g_new0(PurpleRC4CipherPriv, 1);
+
+ purple_rc4_cipher_reset(cipher);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_rc4_cipher_get_gtype(void) {
+ static GType type = 0;
+
+ if(type == 0) {
+ static const GTypeInfo info = {
+ sizeof(PurpleRC4CipherClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)purple_rc4_cipher_class_init,
+ NULL,
+ NULL,
+ sizeof(PurpleRC4Cipher),
+ 0,
+ (GInstanceInitFunc)purple_rc4_cipher_init,
+ NULL,
+ };
+
+ type = g_type_register_static(PURPLE_TYPE_CIPHER,
+ "PurpleRC4Cipher",
+ &info, 0);
+ }
+
+ return type;
+}
+
+PurpleCipher *
+purple_rc4_cipher_new(void) {
+ return g_object_new(PURPLE_TYPE_RC4_CIPHER, NULL);
+}
+
+void
+purple_rc4_cipher_set_key_len(PurpleRC4Cipher *rc4_cipher,
+ gint key_len)
+{
+ g_return_if_fail(PURPLE_IS_RC4_CIPHER(rc4_cipher));
+
+ rc4_cipher->priv->key_len = key_len;
+
+ g_object_notify(G_OBJECT(rc4_cipher), "key_len");
+}
+
+gint
+purple_rc4_cipher_get_key_len(PurpleRC4Cipher *rc4_cipher)
+{
+ g_return_val_if_fail(PURPLE_IS_RC4_CIPHER(rc4_cipher), 0);
+
+ return rc4_cipher->priv->key_len;
+}
============================================================
--- libpurple/rc4cipher.h 98a9b8b7fd4ab55e84015c408c5014611f6c7be4
+++ libpurple/rc4cipher.h 98a9b8b7fd4ab55e84015c408c5014611f6c7be4
@@ -0,0 +1,75 @@
+/**
+ * @file rc4cipher.h Purple RC4 Cipher
+ * @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
+ */
+#ifndef PURPLE_RC4_CIPHER_H
+#define PURPLE_RC4_CIPHER_H
+
+#include <cipher.h>
+
+#define PURPLE_TYPE_RC4_CIPHER (purple_rc4_cipher_get_gtype())
+#define PURPLE_RC4_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_RC4_CIPHER, PurpleRC4Cipher))
+#define PURPLE_RC4_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_RC4_CIPHER, PurpleRC4CipherClass))
+#define PURPLE_IS_RC4_CIPHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_RC4_CIPHER))
+#define PURPLE_IS_RC4_CIPHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), PURPLE_TYPE_RC4_CIPHER))
+#define PURPLE_RC4_CIPHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_RC4_CIPHER, PurpleRC4CipherClass))
+
+typedef struct _PurpleRC4Cipher PurpleRC4Cipher;
+typedef struct _PurpleRC4CipherPriv PurpleRC4CipherPriv;
+typedef struct _PurpleRC4CipherClass PurpleRC4CipherClass;
+
+struct _PurpleRC4Cipher {
+ PurpleCipher gparent;
+
+ PurpleRC4CipherPriv *priv;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+struct _PurpleRC4CipherClass {
+ PurpleCipherClass gparent;
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType purple_rc4_cipher_get_gtype(void);
+
+PurpleCipher *purple_rc4_cipher_new(void);
+
+gint purple_rc4_cipher_get_key_len(PurpleRC4Cipher *rc4_cipher);
+void purple_rc4_cipher_set_key_len(PurpleRC4Cipher *rc4_cipher, gint key_len);
+
+G_END_DECLS
+
+#endif /* PURPLE_RC4_CIPHER_H */
+
+
More information about the Commits
mailing list