changeset 23266:2b997b690500

A patch from QuLogic to eliminate duplicated HMAC-MD5 code in the Jabber prpl by using the cipher API. Fixes #5976 committer: Richard Laager <rlaager@wiktel.com>
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Mon, 02 Jun 2008 05:06:58 +0000
parents 6c4db8059e91
children 043e4b0c274e 74f1a07f452b 9f91d6e0983c
files libpurple/protocols/jabber/auth.c
diffstat 1 files changed, 12 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/auth.c	Sun Jun 01 21:36:43 2008 +0000
+++ b/libpurple/protocols/jabber/auth.c	Mon Jun 02 05:06:58 2008 +0000
@@ -589,75 +589,6 @@
 	}
 }
 
-/*!
- * @brief Given the server challenge (message) and the key (password), calculate the HMAC-MD5 digest
- *
- * This is the crammd5 response.  Inspired by cyrus-sasl's _sasl_hmac_md5()
- */
-static void
-auth_hmac_md5(const char *challenge, size_t challenge_len, const char *key, size_t key_len, guchar *digest)
-{
-	PurpleCipher *cipher;
-	PurpleCipherContext *context;
-	int i;
-	/* inner padding - key XORd with ipad */
-	unsigned char k_ipad[65];    
-	/* outer padding - key XORd with opad */
-	unsigned char k_opad[65];    
-
-	cipher = purple_ciphers_find_cipher("md5");
-
-	/* if key is longer than 64 bytes reset it to key=MD5(key) */
-	if (strlen(key) > 64) {
-		guchar keydigest[16];
-
-		context = purple_cipher_context_new(cipher, NULL);
-		purple_cipher_context_append(context, (const guchar *)key, strlen(key));
-		purple_cipher_context_digest(context, 16, keydigest, NULL);
-		purple_cipher_context_destroy(context);
-
-		key = (char *)keydigest;
-		key_len = 16;
-	} 
-
-	/*
-	 * the HMAC_MD5 transform looks like:
-	 *
-	 * MD5(K XOR opad, MD5(K XOR ipad, text))
-	 *
-	 * where K is an n byte key
-	 * ipad is the byte 0x36 repeated 64 times
-	 * opad is the byte 0x5c repeated 64 times
-	 * and text is the data being protected
-	 */
-
-	/* start out by storing key in pads */
-	memset(k_ipad, '\0', sizeof k_ipad);
-	memset(k_opad, '\0', sizeof k_opad);
-	memcpy(k_ipad, (void *)key, key_len);
-	memcpy(k_opad, (void *)key, key_len);
-
-	/* XOR key with ipad and opad values */
-	for (i=0; i<64; i++) {
-		k_ipad[i] ^= 0x36;
-		k_opad[i] ^= 0x5c;
-	}
-
-	/* perform inner MD5 */
-	context = purple_cipher_context_new(cipher, NULL);
-	purple_cipher_context_append(context, k_ipad, 64); /* start with inner pad */
-	purple_cipher_context_append(context, (const guchar *)challenge, challenge_len); /* then text of datagram */
-	purple_cipher_context_digest(context, 16, digest, NULL); /* finish up 1st pass */
-	purple_cipher_context_destroy(context);
-
-	/* perform outer MD5 */	
-	context = purple_cipher_context_new(cipher, NULL);
-	purple_cipher_context_append(context, k_opad, 64); /* start with outer pad */
-	purple_cipher_context_append(context, digest, 16); /* then results of 1st hash */
-	purple_cipher_context_digest(context, 16, digest, NULL); /* finish up 2nd pass */
-	purple_cipher_context_destroy(context);
-}
-
 static void auth_old_cb(JabberStream *js, xmlnode *packet, gpointer data)
 {
 	JabberIq *iq;
@@ -703,14 +634,19 @@
 			jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
 			jabber_iq_send(iq);
 
-		} else if(js->stream_id && xmlnode_get_child(query, "crammd5")) {
+		} else if(js->stream_id && (x = xmlnode_get_child(query, "crammd5"))) {
 			const char *challenge;
-			guchar digest[16];
-			char h[33], *p;
-			int i;
+			gchar digest[33];
+			PurpleCipherContext *hmac;
 
-			challenge = xmlnode_get_attrib(xmlnode_get_child(query, "crammd5"), "challenge");
-			auth_hmac_md5(challenge, strlen(challenge), pw, strlen(pw), digest);
+			/* Calculate the MHAC-MD5 digest */
+			challenge = xmlnode_get_attrib(x, "challenge");
+			hmac = purple_cipher_context_new_by_name("hmac", NULL);
+			purple_cipher_context_set_option(hmac, "hash", "md5");
+			purple_cipher_context_set_key(hmac, (guchar *)pw);
+			purple_cipher_context_append(hmac, (guchar *)challenge, strlen(challenge));
+			purple_cipher_context_digest_to_str(hmac, 33, digest, NULL);
+			purple_cipher_context_destroy(hmac);
 
 			/* Create the response query */
 			iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
@@ -723,11 +659,7 @@
 
 			x = xmlnode_new_child(query, "crammd5");
 
-			/* Translate the digest to a hexadecimal notation */
-			p = h;
-			for(i=0; i<16; i++, p+=2)
-				snprintf(p, 3, "%02x", digest[i]);
-			xmlnode_insert_data(x, h, -1);
+			xmlnode_insert_data(x, digest, 32);
 
 			jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
 			jabber_iq_send(iq);