--- a/libpurple/cipher.c Sun May 05 16:29:14 2013 +0200
+++ b/libpurple/cipher.c Sun May 05 18:25:31 2013 +0200
@@ -120,34 +120,42 @@
purple_cipher_digest_region(const gchar *name, const guchar *data,
size_t data_len, guchar digest[], size_t out_size)
PurpleCipherContext *context;
- g_return_val_if_fail(name, FALSE);
- g_return_val_if_fail(data, FALSE);
+ g_return_val_if_fail(name, -1); + g_return_val_if_fail(data, -1); cipher = purple_ciphers_find_cipher(name);
- g_return_val_if_fail(cipher, FALSE);
+ g_return_val_if_fail(cipher, -1); - if(!cipher->ops->append || !cipher->ops->digest) {
+ if(!cipher->ops->append || !cipher->ops->digest || !cipher->ops->get_digest_size) { purple_debug_warning("cipher", "purple_cipher_region failed: "
"the %s cipher does not support appending and or "
"digesting.", cipher->name);
context = purple_cipher_context_new(cipher, NULL);
+ digest_size = purple_cipher_context_get_digest_size(context); + if (out_size < digest_size) { + purple_debug_error("cipher", "purple_cipher_region failed: " + "provided output buffer too small\n"); + purple_cipher_context_destroy(context); purple_cipher_context_append(context, data, data_len);
- ret = purple_cipher_context_digest(context, digest, out_size);
+ succ = purple_cipher_context_digest(context, digest, out_size); purple_cipher_context_destroy(context);
+ return succ ? digest_size : -1; /******************************************************************************
--- a/libpurple/cipher.h Sun May 05 16:29:14 2013 +0200
+++ b/libpurple/cipher.h Sun May 05 18:25:31 2013 +0200
@@ -169,9 +169,9 @@
* @param digest The returned digest
* @param out_size The size of digest buffer
- * @return @c TRUE if successful, @c FALSE otherwise
+ * @return The count of bytes written, or -1 if failed -gboolean purple_cipher_digest_region(const gchar *name, const guchar *data, size_t data_len, guchar digest[], size_t out_size);
+ssize_t purple_cipher_digest_region(const gchar *name, const guchar *data, size_t data_len, guchar digest[], size_t out_size); /******************************************************************************/
--- a/libpurple/plugins/perl/common/Cipher.xs Sun May 05 16:29:14 2013 +0200
+++ b/libpurple/plugins/perl/common/Cipher.xs Sun May 05 18:25:31 2013 +0200
@@ -25,6 +25,7 @@
+ const_iv(GET_DIGEST_SIZE), @@ -34,7 +35,6 @@
const_iv(SET_BATCH_MODE),
const_iv(GET_BATCH_MODE),
const_iv(GET_BLOCK_SIZE),
- const_iv(SET_KEY_WITH_LEN),
@@ -54,28 +54,30 @@
purple_cipher_get_capabilities(cipher)
-purple_cipher_digest_region(name, data_sv, in_len, digest)
+purple_cipher_digest_region(name, data_sv, data_len, digest)
+ size_t max_digest_len = 100; data = (guchar *)SvPV(data_sv, data_len);
SvUPGRADE(digest, SVt_PV);
- buff = (guchar *)SvGROW(digest, in_len);
- ret = purple_cipher_digest_region(name, data, data_len, in_len, buff, &RETVAL);
+ buff = (guchar *)SvGROW(digest, max_digest_len); + digest_len = purple_cipher_digest_region(name, data, data_len, buff, max_digest_len); SvSetSV_nosteal(digest, &PL_sv_undef);
+ SvCUR_set(digest, digest_len); - SvCUR_set(digest, RETVAL);
@@ -171,110 +173,120 @@
purple_cipher_context_append(Purple::Cipher::Context context, guchar *data, size_t length(data))
-purple_cipher_context_digest(context, in_len, digest)
+purple_cipher_context_digest(context, digest) Purple::Cipher::Context context
+ digest_size = purple_cipher_context_get_digest_size(context); SvUPGRADE(digest, SVt_PV);
- buff = (guchar *)SvGROW(digest, in_len);
- ret = purple_cipher_context_digest(context, in_len, buff, &RETVAL);
+ buff = (guchar *)SvGROW(digest, digest_size); + if (purple_cipher_context_digest(context, buff, digest_size)) { + SvCUR_set(digest, digest_size); SvSetSV_nosteal(digest, &PL_sv_undef);
- SvCUR_set(digest, RETVAL);
-purple_cipher_context_digest_to_str(context, in_len, digest_s)
+purple_cipher_context_digest_to_str(context, digest_s) Purple::Cipher::Context context
+ size_t digest_size, str_len; - in_len += 1; /* perl shouldn't need to care about '\0' at the end */
+ digest_size = purple_cipher_context_get_digest_size(context); + str_len = 2 * digest_size; SvUPGRADE(digest_s, SVt_PV);
- buff = SvGROW(digest_s, in_len);
- ret = purple_cipher_context_digest_to_str(context, in_len, buff, &RETVAL);
+ buff = SvGROW(digest_s, str_len + 1); + if (purple_cipher_context_digest_to_str(context, buff, str_len + 1)) { + SvCUR_set(digest_s, str_len); SvSetSV_nosteal(digest_s, &PL_sv_undef);
- SvCUR_set(digest_s, RETVAL);
-purple_cipher_context_encrypt(context, data_sv, output, OUTLIST size_t outlen)
+purple_cipher_context_encrypt(context, input, output) Purple::Cipher::Context context
+ size_t input_len, output_len; - data = (guchar *)SvPV(data_sv, datalen);
+ data = (guchar *)SvPV(input, input_len); + output_len = input_len + purple_cipher_context_get_block_size(context); SvUPGRADE(output, SVt_PV);
- buff = (guchar *)SvGROW(output, datalen);
- RETVAL = purple_cipher_context_encrypt(context, data, datalen, buff, &outlen);
+ buff = (guchar *)SvGROW(output, output_len); + ret = purple_cipher_context_encrypt(context, data, input_len, buff, output_len); - SvCUR_set(output, outlen);
+ SvCUR_set(output, ret); SvSetSV_nosteal(output, &PL_sv_undef);
-purple_cipher_context_decrypt(context, data_sv, output, OUTLIST size_t outlen)
+purple_cipher_context_decrypt(context, input, output) Purple::Cipher::Context context
+ size_t input_len, output_len; - data = (guchar *)SvPV(data_sv, datalen);
+ data = (guchar *)SvPV(input, input_len); + output_len = input_len + purple_cipher_context_get_block_size(context); SvUPGRADE(output, SVt_PV);
- buff = (guchar *)SvGROW(output, datalen);
- RETVAL = purple_cipher_context_decrypt(context, data, datalen, buff, &outlen);
+ buff = (guchar *)SvGROW(output, output_len); + ret = purple_cipher_context_decrypt(context, data, input_len, buff, output_len); - SvCUR_set(output, outlen);
+ SvCUR_set(output, ret); SvSetSV_nosteal(output, &PL_sv_undef);
-purple_cipher_context_set_salt(context, salt)
+purple_cipher_context_set_salt(context, salt, len) Purple::Cipher::Context context
purple_cipher_context_get_salt_size(context)
Purple::Cipher::Context context
-purple_cipher_context_set_key(context, key)
+purple_cipher_context_set_key(context, key, len) Purple::Cipher::Context context
purple_cipher_context_get_key_size(context)
@@ -302,7 +314,3 @@
Purple::Cipher::Context context
Purple::Cipher::BatchMode mode
-purple_cipher_context_set_key_with_len(Purple::Cipher::Context context, guchar *key, size_t length(key))