static char * generate_response_value(JabberID *jid, const char *passwd, const char *nonce, const char *cnonce, const char *a2, const char *realm) { PurpleHash *hash; guchar result[16]; size_t a1len; gchar *a1, *convnode=NULL, *convpasswd = NULL, *ha1, *ha2, *kd, *x, *z; if((convnode = g_convert(jid->node, -1, "iso-8859-1", "utf-8", NULL, NULL, NULL)) == NULL) { convnode = g_strdup(jid->node); } if(passwd && ((convpasswd = g_convert(passwd, -1, "iso-8859-1", "utf-8", NULL, NULL, NULL)) == NULL)) { convpasswd = g_strdup(passwd); } hash = purple_md5_hash_new(); x = g_strdup_printf("%s:%s:%s", convnode, realm, convpasswd ? convpasswd : ""); purple_hash_append(hash, (const guchar *)x, strlen(x)); purple_hash_digest(hash, result, sizeof(result)); a1 = g_strdup_printf("xxxxxxxxxxxxxxxx:%s:%s", nonce, cnonce); a1len = strlen(a1); g_memmove(a1, result, 16); purple_hash_reset(hash); purple_hash_append(hash, (const guchar *)a1, a1len); purple_hash_digest(hash, result, sizeof(result)); ha1 = purple_base16_encode(result, 16); purple_hash_reset(hash); purple_hash_append(hash, (const guchar *)a2, strlen(a2)); purple_hash_digest(hash, result, sizeof(result)); ha2 = purple_base16_encode(result, 16); kd = g_strdup_printf("%s:%s:00000001:%s:auth:%s", ha1, nonce, cnonce, ha2); purple_hash_reset(hash); purple_hash_append(hash, (const guchar *)kd, strlen(kd)); purple_hash_digest(hash, result, sizeof(result)); g_object_unref(hash); z = purple_base16_encode(result, 16); g_free(convnode); g_free(convpasswd); g_free(x); g_free(a1); g_free(ha1); g_free(ha2); g_free(kd); return z; }
static void purple_hmac_cipher_set_key(PurpleCipher *cipher, const guchar *key, size_t key_len) { PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher); gsize block_size, i; guchar *full_key; g_return_if_fail(priv->hash); g_free(priv->ipad); g_free(priv->opad); block_size = purple_hash_get_block_size(priv->hash); priv->ipad = g_malloc(block_size); priv->opad = g_malloc(block_size); if (key_len > block_size) { purple_hash_reset(priv->hash); purple_hash_append(priv->hash, key, key_len); key_len = purple_hash_get_digest_size(priv->hash); full_key = g_malloc(key_len); purple_hash_digest(priv->hash, full_key, key_len); } else { full_key = g_memdup(key, key_len); } if (key_len < block_size) { full_key = g_realloc(full_key, block_size); memset(full_key + key_len, 0, block_size - key_len); } for(i = 0; i < block_size; i++) { priv->ipad[i] = 0x36 ^ full_key[i]; priv->opad[i] = 0x5c ^ full_key[i]; } g_free(full_key); purple_hash_reset(priv->hash); purple_hash_append(priv->hash, priv->ipad, block_size); }
static void cipher_test_sha1(void) { PurpleHash *hash; gchar digest[41]; gint i = 0; gboolean ret; hash = purple_sha1_hash_new(); if(!hash) { purple_debug_info("cipher-test", "could not find sha1 cipher, not testing\n"); return; } purple_debug_info("cipher-test", "Running sha1 tests\n"); while(sha1_tests[i].answer) { purple_debug_info("cipher-test", "Test %02d:\n", i); purple_debug_info("cipher-test", "Testing '%s'\n", (sha1_tests[i].question != NULL) ? sha1_tests[i].question : "'a'x1000, 1000 times"); if(sha1_tests[i].question) { purple_hash_append(hash, (guchar *)sha1_tests[i].question, strlen(sha1_tests[i].question)); } else { gint j; guchar buff[1000]; memset(buff, 'a', 1000); for(j = 0; j < 1000; j++) purple_hash_append(hash, buff, 1000); } ret = purple_hash_digest_to_str(hash, digest, sizeof(digest)); if(!ret) { purple_debug_info("cipher-test", "failed\n"); } else { purple_debug_info("cipher-test", "\tGot: %s\n", digest); purple_debug_info("cipher-test", "\tWanted: %s\n", sha1_tests[i].answer); } purple_hash_reset(hash); i++; } g_object_unref(hash); purple_debug_info("cipher-test", "sha1 tests completed\n\n"); }
/******************************************************************************* * Cipher Stuff ******************************************************************************/ static void purple_hmac_cipher_reset(PurpleCipher *cipher) { PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher); if(PURPLE_IS_HASH(priv->hash)) purple_hash_reset(priv->hash); g_free(priv->ipad); priv->ipad = NULL; g_free(priv->opad); priv->opad = NULL; }
static void cipher_test_md5(void) { PurpleHash *hash; gchar digest[33]; gboolean ret; gint i = 0; hash = purple_md5_hash_new(); if(!hash) { purple_debug_info("cipher-test", "could not find md5 cipher, not testing\n"); return; } purple_debug_info("cipher-test", "Running md5 tests\n"); while(md5_tests[i].answer) { purple_debug_info("cipher-test", "Test %02d:\n", i); purple_debug_info("cipher-test", "Testing '%s'\n", md5_tests[i].question); purple_hash_append(hash, (guchar *)md5_tests[i].question, strlen(md5_tests[i].question)); ret = purple_hash_digest_to_str(hash, digest, sizeof(digest)); if(!ret) { purple_debug_info("cipher-test", "failed\n"); } else { purple_debug_info("cipher-test", "\tGot: %s\n", digest); purple_debug_info("cipher-test", "\tWanted: %s\n", md5_tests[i].answer); } purple_hash_reset(hash); i++; } g_object_unref(hash); purple_debug_info("cipher-test", "md5 tests completed\n\n"); }
static gboolean purple_hmac_cipher_digest(PurpleCipher *cipher, guchar *out, size_t len) { PurpleHMACCipherPrivate *priv = PURPLE_HMAC_CIPHER_GET_PRIVATE(cipher); guchar *digest = NULL; size_t hash_len, block_size; gboolean result = FALSE; g_return_val_if_fail(PURPLE_IS_HASH(priv->hash), FALSE); hash_len = purple_hash_get_digest_size(priv->hash); g_return_val_if_fail(hash_len > 0, FALSE); block_size = purple_hash_get_block_size(priv->hash); digest = g_malloc(hash_len); /* get the digest of the data */ result = purple_hash_digest(priv->hash, digest, hash_len); purple_hash_reset(priv->hash); if(!result) { g_free(digest); return FALSE; } /* now append the opad and the digest from above */ purple_hash_append(priv->hash, priv->opad, block_size); purple_hash_append(priv->hash, digest, hash_len); /* do our last digest */ result = purple_hash_digest(priv->hash, out, len); /* cleanup */ g_free(digest); return result; }
MsnObject* msn_object_new_from_image(PurpleStoredImage *img, const char *location, const char *creator, MsnObjectType type) { MsnObject *msnobj; PurpleHash *hash; char *buf; gconstpointer data; size_t size; char *base64; unsigned char digest[20]; msnobj = NULL; if (img == NULL) return msnobj; size = purple_imgstore_get_size(img); data = purple_imgstore_get_data(img); /* New object */ msnobj = msn_object_new(); msn_object_set_local(msnobj); msn_object_set_type(msnobj, type); msn_object_set_location(msnobj, location); msn_object_set_creator(msnobj, creator); msn_object_set_image(msnobj, img); /* Compute the SHA1D field. */ memset(digest, 0, sizeof(digest)); hash = purple_sha1_hash_new(); purple_hash_append(hash, data, size); purple_hash_digest(hash, digest, sizeof(digest)); base64 = purple_base64_encode(digest, sizeof(digest)); msn_object_set_sha1d(msnobj, base64); g_free(base64); msn_object_set_size(msnobj, size); /* Compute the SHA1C field. */ buf = g_strdup_printf( "Creator%sSize%dType%dLocation%sFriendly%sSHA1D%s", msn_object_get_creator(msnobj), msn_object_get_size(msnobj), msn_object_get_type(msnobj), msn_object_get_location(msnobj), msn_object_get_friendly(msnobj), msn_object_get_sha1d(msnobj)); memset(digest, 0, sizeof(digest)); purple_hash_reset(hash); purple_hash_append(hash, (const guchar *)buf, strlen(buf)); purple_hash_digest(hash, digest, sizeof(digest)); g_object_unref(hash); g_free(buf); base64 = purple_base64_encode(digest, sizeof(digest)); msn_object_set_sha1c(msnobj, base64); g_free(base64); return msnobj; }