Mercurial > pidgin
changeset 23264: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 |
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);