/pidgin/main: 773899cbd05a: ciphers cleanup: salt and digest len...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Sun May 5 08:59:19 EDT 2013


Changeset: 773899cbd05ad29b39bc7a960ff3531149f4ae8e
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2013-05-05 14:59 +0200
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/773899cbd05a

Description:

ciphers cleanup: salt and digest lengths

diffstat:

 libpurple/cipher.c                           |  68 ++++++++++++++++++---------
 libpurple/cipher.h                           |  53 +++++++++++++--------
 libpurple/ciphers/des.c                      |   2 +
 libpurple/ciphers/gchecksum.c                |  29 +++++++----
 libpurple/ciphers/hmac.c                     |  29 +++++++++--
 libpurple/ciphers/md4.c                      |  13 +++-
 libpurple/ciphers/rc4.c                      |   1 +
 libpurple/ntlm.c                             |   2 +-
 libpurple/plugins/ciphertest.c               |   6 +-
 libpurple/protocols/bonjour/bonjour_ft.c     |   4 +-
 libpurple/protocols/gg/oauth/oauth.c         |   2 +-
 libpurple/protocols/jabber/auth.c            |   2 +-
 libpurple/protocols/jabber/auth_digest_md5.c |   8 +-
 libpurple/protocols/jabber/auth_scram.c      |   8 +-
 libpurple/protocols/jabber/caps.c            |   4 +-
 libpurple/protocols/jabber/jutil.c           |   2 +-
 libpurple/protocols/msn/directconn.c         |   2 +-
 libpurple/protocols/msn/msnutils.c           |   2 +-
 libpurple/protocols/msn/nexus.c              |  16 +++---
 libpurple/protocols/msn/notification.c       |   2 +-
 libpurple/protocols/msn/object.c             |   4 +-
 libpurple/protocols/myspace/myspace.c        |   4 +-
 libpurple/protocols/oscar/clientlogin.c      |   2 +-
 libpurple/protocols/oscar/family_auth.c      |   4 +-
 libpurple/protocols/oscar/family_oservice.c  |   4 +-
 libpurple/protocols/oscar/oscar.c            |   2 +-
 libpurple/protocols/yahoo/libymsg.c          |   2 +-
 libpurple/proxy.c                            |   6 +-
 28 files changed, 172 insertions(+), 111 deletions(-)

diffs (truncated from 928 to 300 lines):

diff --git a/libpurple/cipher.c b/libpurple/cipher.c
--- a/libpurple/cipher.c
+++ b/libpurple/cipher.c
@@ -96,6 +96,8 @@ purple_cipher_get_capabilities(PurpleCip
 		caps |= PURPLE_CIPHER_CAPS_APPEND;
 	if(ops->digest)
 		caps |= PURPLE_CIPHER_CAPS_DIGEST;
+	if(ops->get_digest_size)
+		caps |= PURPLE_CIPHER_CAPS_GET_DIGEST_SIZE;
 	if(ops->encrypt)
 		caps |= PURPLE_CIPHER_CAPS_ENCRYPT;
 	if(ops->decrypt)
@@ -118,8 +120,7 @@ purple_cipher_get_capabilities(PurpleCip
 
 gboolean
 purple_cipher_digest_region(const gchar *name, const guchar *data,
-						  size_t data_len, size_t in_len,
-						  guchar digest[], size_t *out_len)
+	size_t data_len, guchar digest[], size_t out_size)
 {
 	PurpleCipher *cipher;
 	PurpleCipherContext *context;
@@ -141,7 +142,7 @@ purple_cipher_digest_region(const gchar 
 
 	context = purple_cipher_context_new(cipher, NULL);
 	purple_cipher_context_append(context, data, data_len);
-	ret = purple_cipher_context_digest(context, in_len, digest, out_len);
+	ret = purple_cipher_context_digest(context, digest, out_size);
 	purple_cipher_context_destroy(context);
 
 	return ret;
@@ -403,8 +404,8 @@ purple_cipher_context_append(PurpleCiphe
 }
 
 gboolean
-purple_cipher_context_digest(PurpleCipherContext *context, size_t in_len,
-						   guchar digest[], size_t *out_len)
+purple_cipher_context_digest(PurpleCipherContext *context, guchar digest[],
+	size_t len)
 {
 	PurpleCipher *cipher = NULL;
 
@@ -413,7 +414,7 @@ purple_cipher_context_digest(PurpleCiphe
 	cipher = context->cipher;
 
 	if(cipher->ops && cipher->ops->digest)
-		return cipher->ops->digest(context, in_len, digest, out_len);
+		return cipher->ops->digest(context, digest, len);
 	else {
 		purple_debug_warning("cipher", "the %s cipher does not support the digest "
 						"operation\n", cipher->name);
@@ -422,33 +423,52 @@ purple_cipher_context_digest(PurpleCiphe
 }
 
 gboolean
-purple_cipher_context_digest_to_str(PurpleCipherContext *context, size_t in_len,
-								   gchar digest_s[], size_t *out_len)
+purple_cipher_context_digest_to_str(PurpleCipherContext *context,
+	gchar digest_s[], size_t len)
 {
 	/* 8k is a bit excessive, will tweak later. */
 	guchar digest[BUF_LEN * 4];
 	gint n = 0;
-	size_t dlen = 0;
+	size_t digest_size;
 
 	g_return_val_if_fail(context, FALSE);
 	g_return_val_if_fail(digest_s, FALSE);
 
-	if(!purple_cipher_context_digest(context, sizeof(digest), digest, &dlen))
+	digest_size = purple_cipher_context_get_digest_size(context);
+
+	g_return_val_if_fail(digest_size <= BUF_LEN * 4, FALSE);
+
+	if(!purple_cipher_context_digest(context, digest, sizeof(digest)))
 		return FALSE;
 
-	/* in_len must be greater than dlen * 2 so we have room for the NUL. */
-	if(in_len <= dlen * 2)
-		return FALSE;
+	/* Every digest byte occupies 2 chars + the NUL at the end. */
+	g_return_val_if_fail(digest_size * 2 + 1 <= len, FALSE);
 
-	for(n = 0; n < dlen; n++)
+	for(n = 0; n < digest_size; n++)
 		sprintf(digest_s + (n * 2), "%02x", digest[n]);
 
 	digest_s[n * 2] = '\0';
 
-	if(out_len)
-		*out_len = dlen * 2;
+	return TRUE;
+}
 
-	return TRUE;
+size_t
+purple_cipher_context_get_digest_size(PurpleCipherContext *context)
+{
+	PurpleCipher *cipher = NULL;
+
+	g_return_val_if_fail(context, 0);
+
+	cipher = context->cipher;
+	g_return_val_if_fail(cipher, 0);
+
+	if(cipher->ops && cipher->ops->get_digest_size)
+		return cipher->ops->get_digest_size(context);
+	else {
+		purple_debug_warning("cipher", "The %s cipher does not support "
+			"the get_digest_size operation\n", cipher->name);
+		return 0;
+	}
 }
 
 gint
@@ -500,7 +520,7 @@ purple_cipher_context_decrypt(PurpleCiph
 }
 
 void
-purple_cipher_context_set_salt(PurpleCipherContext *context, guchar *salt) {
+purple_cipher_context_set_salt(PurpleCipherContext *context, guchar *salt, size_t len) {
 	PurpleCipher *cipher = NULL;
 
 	g_return_if_fail(context);
@@ -509,7 +529,7 @@ purple_cipher_context_set_salt(PurpleCip
 	g_return_if_fail(cipher);
 
 	if(cipher->ops && cipher->ops->set_salt)
-		cipher->ops->set_salt(context, salt);
+		cipher->ops->set_salt(context, salt, len);
 	else
 		purple_debug_warning("cipher", "the %s cipher does not support the "
 						"set_salt operation\n", cipher->name);
@@ -665,7 +685,7 @@ gchar *purple_cipher_http_digest_calcula
 			return NULL;
 		}
 
-		purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
+		purple_cipher_context_digest(context, digest, sizeof(digest));
 		purple_cipher_context_destroy(context);
 
 		context = purple_cipher_context_new(cipher, NULL);
@@ -676,7 +696,7 @@ gchar *purple_cipher_http_digest_calcula
 		purple_cipher_context_append(context, (guchar *)client_nonce, strlen(client_nonce));
 	}
 
-	purple_cipher_context_digest_to_str(context, sizeof(hash), hash, NULL);
+	purple_cipher_context_digest_to_str(context, hash, sizeof(hash));
 	purple_cipher_context_destroy(context);
 
 	return g_strdup(hash);
@@ -737,14 +757,14 @@ gchar *purple_cipher_http_digest_calcula
 
 		context2 = purple_cipher_context_new(cipher, NULL);
 		purple_cipher_context_append(context2, (guchar *)entity, strlen(entity));
-		purple_cipher_context_digest_to_str(context2, sizeof(entity_hash), entity_hash, NULL);
+		purple_cipher_context_digest_to_str(context2, entity_hash, sizeof(entity_hash));
 		purple_cipher_context_destroy(context2);
 
 		purple_cipher_context_append(context, (guchar *)":", 1);
 		purple_cipher_context_append(context, (guchar *)entity_hash, strlen(entity_hash));
 	}
 
-	purple_cipher_context_digest_to_str(context, sizeof(hash2), hash2, NULL);
+	purple_cipher_context_digest_to_str(context, hash2, sizeof(hash2));
 	purple_cipher_context_destroy(context);
 
 	context = purple_cipher_context_new(cipher, NULL);
@@ -780,7 +800,7 @@ gchar *purple_cipher_http_digest_calcula
 	}
 
 	purple_cipher_context_append(context, (guchar *)hash2, strlen(hash2));
-	purple_cipher_context_digest_to_str(context, sizeof(hash2), hash2, NULL);
+	purple_cipher_context_digest_to_str(context, hash2, sizeof(hash2));
 	purple_cipher_context_destroy(context);
 
 	return g_strdup(hash2);
diff --git a/libpurple/cipher.h b/libpurple/cipher.h
--- a/libpurple/cipher.h
+++ b/libpurple/cipher.h
@@ -58,15 +58,16 @@ typedef enum {
 	PURPLE_CIPHER_CAPS_SET_IV           = 1 << 6,   /**< Set IV flag		*/
 	PURPLE_CIPHER_CAPS_APPEND           = 1 << 7,   /**< Append flag		*/
 	PURPLE_CIPHER_CAPS_DIGEST           = 1 << 8,   /**< Digest flag		*/
-	PURPLE_CIPHER_CAPS_ENCRYPT          = 1 << 9,   /**< Encrypt flag		*/
-	PURPLE_CIPHER_CAPS_DECRYPT          = 1 << 10,  /**< Decrypt flag		*/
-	PURPLE_CIPHER_CAPS_SET_SALT         = 1 << 11,  /**< Set salt flag		*/
-	PURPLE_CIPHER_CAPS_GET_SALT_SIZE    = 1 << 12,  /**< Get salt size flag	*/
-	PURPLE_CIPHER_CAPS_SET_KEY          = 1 << 13,  /**< Set key flag		*/
-	PURPLE_CIPHER_CAPS_SET_BATCH_MODE   = 1 << 14,  /**< Set batch mode flag */
-	PURPLE_CIPHER_CAPS_GET_BATCH_MODE   = 1 << 15,  /**< Get batch mode flag */
-	PURPLE_CIPHER_CAPS_GET_BLOCK_SIZE   = 1 << 16,  /**< The get block size flag */
-	PURPLE_CIPHER_CAPS_UNKNOWN          = 1 << 17   /**< Unknown			*/
+	PURPLE_CIPHER_CAPS_GET_DIGEST_SIZE  = 1 << 9,   /**< The get digest size flag */
+	PURPLE_CIPHER_CAPS_ENCRYPT          = 1 << 10,  /**< Encrypt flag		*/
+	PURPLE_CIPHER_CAPS_DECRYPT          = 1 << 11,  /**< Decrypt flag		*/
+	PURPLE_CIPHER_CAPS_SET_SALT         = 1 << 12,  /**< Set salt flag		*/
+	PURPLE_CIPHER_CAPS_GET_SALT_SIZE    = 1 << 13,  /**< Get salt size flag	*/
+	PURPLE_CIPHER_CAPS_SET_KEY          = 1 << 14,  /**< Set key flag		*/
+	PURPLE_CIPHER_CAPS_SET_BATCH_MODE   = 1 << 15,  /**< Set batch mode flag */
+	PURPLE_CIPHER_CAPS_GET_BATCH_MODE   = 1 << 16,  /**< Get batch mode flag */
+	PURPLE_CIPHER_CAPS_GET_BLOCK_SIZE   = 1 << 17,  /**< The get block size flag */
+	PURPLE_CIPHER_CAPS_UNKNOWN          = 1 << 18   /**< Unknown			*/
 } PurpleCipherCaps;
 
 /**
@@ -95,7 +96,10 @@ struct _PurpleCipherOps {
 	void (*append)(PurpleCipherContext *context, const guchar *data, size_t len);
 
 	/** The digest function */
-	gboolean (*digest)(PurpleCipherContext *context, size_t in_len, guchar digest[], size_t *out_len);
+	gboolean (*digest)(PurpleCipherContext *context, guchar digest[], size_t len);
+
+	/** The get digest size function */
+	size_t (*get_digest_size)(PurpleCipherContext *context);
 
 	/** The encrypt function */
 	int (*encrypt)(PurpleCipherContext *context, const guchar data[], size_t len, guchar output[], size_t *outlen);
@@ -104,7 +108,7 @@ struct _PurpleCipherOps {
 	int (*decrypt)(PurpleCipherContext *context, const guchar data[], size_t len, guchar output[], size_t *outlen);
 
 	/** The set salt function */
-	void (*set_salt)(PurpleCipherContext *context, guchar *salt);
+	void (*set_salt)(PurpleCipherContext *context, guchar *salt, size_t len);
 
 	/** The get salt size function */
 	size_t (*get_salt_size)(PurpleCipherContext *context);
@@ -158,13 +162,12 @@ guint purple_cipher_get_capabilities(Pur
  * @param name     The cipher's name
  * @param data     The data to hash
  * @param data_len The length of the data
- * @param in_len   The length of the buffer
  * @param digest   The returned digest
- * @param out_len  The length written
+ * @param out_size The size of digest buffer
  *
  * @return @c TRUE if successful, @c FALSE otherwise
  */
-gboolean purple_cipher_digest_region(const gchar *name, const guchar *data, size_t data_len, size_t in_len, guchar digest[], size_t *out_len);
+gboolean purple_cipher_digest_region(const gchar *name, const guchar *data, size_t data_len, guchar digest[], size_t out_size);
 
 /*@}*/
 /******************************************************************************/
@@ -314,21 +317,28 @@ void purple_cipher_context_append(Purple
  * Digests a context
  *
  * @param context The context to digest
- * @param in_len  The length of the buffer
  * @param digest  The return buffer for the digest
- * @param out_len The length of the returned value
+ * @param len     The length of the buffer
  */
-gboolean purple_cipher_context_digest(PurpleCipherContext *context, size_t in_len, guchar digest[], size_t *out_len);
+gboolean purple_cipher_context_digest(PurpleCipherContext *context, guchar digest[], size_t len);
 
 /**
  * Converts a guchar digest into a hex string
  *
  * @param context  The context to get a digest from
- * @param in_len   The length of the buffer
  * @param digest_s The return buffer for the string digest
- * @param out_len  The length of the returned value
+ * @param len      The length of the buffer
  */
-gboolean purple_cipher_context_digest_to_str(PurpleCipherContext *context, size_t in_len, gchar digest_s[], size_t *out_len);
+gboolean purple_cipher_context_digest_to_str(PurpleCipherContext *context, gchar digest_s[], size_t len);
+
+/**
+ * Gets the digest size of a context
+ *
+ * @param context The context whose digest size to get
+ *
+ * @return The digest size of the context
+ */
+size_t purple_cipher_context_get_digest_size(PurpleCipherContext *context);
 
 /**
  * Encrypts data using the context
@@ -361,8 +371,9 @@ gint purple_cipher_context_decrypt(Purpl
  *
  * @param context The context whose salt to set
  * @param salt    The salt
+ * @param len     The length of the salt
  */
-void purple_cipher_context_set_salt(PurpleCipherContext *context, guchar *salt);
+void purple_cipher_context_set_salt(PurpleCipherContext *context, guchar *salt, size_t len);
 
 /**
  * Gets the size of the salt if the cipher supports it
diff --git a/libpurple/ciphers/des.c b/libpurple/ciphers/des.c
--- a/libpurple/ciphers/des.c
+++ b/libpurple/ciphers/des.c
@@ -471,6 +471,7 @@ static PurpleCipherOps DESOps = {
 	NULL,              /* set iv */
 	NULL,              /* append */
 	NULL,              /* digest */
+	NULL,              /* get_digest_size */
 	des_encrypt,       /* encrypt */
 	des_decrypt,       /* decrypt */
 	NULL,              /* set salt */



More information about the Commits mailing list