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;
}
Esempio n. 2
0
/**
 * @return A Newly allocated base16 encoded version of the md5
 *         signature calculated using the algorithm described on the
 *         Facebook developer wiki.  This string must be g_free'd.
 */
static char *generate_signature(const char *api_secret, const GTree *params)
{
	GString *tmp;
	unsigned char hashval[16];

	tmp = g_string_new(NULL);
	g_tree_foreach((GTree *)params, concat_params, tmp);
	g_string_append(tmp, api_secret);

	purple_cipher_digest_region("md5", (const unsigned char *)tmp->str,
			tmp->len, sizeof(hashval), hashval, NULL);
	g_string_free(tmp, TRUE);

	return purple_base16_encode(hashval, sizeof(hashval));
}
Esempio n. 3
0
static char *
generate_response_value(JabberID *jid, const char *passwd, const char *nonce,
		const char *cnonce, const char *a2, const char *realm)
{
	PurpleCipher *cipher;
	PurpleCipherContext *context;
	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);
	}

	cipher = purple_ciphers_find_cipher("md5");
	context = purple_cipher_context_new(cipher, NULL);

	x = g_strdup_printf("%s:%s:%s", convnode, realm, convpasswd ? convpasswd : "");
	purple_cipher_context_append(context, (const guchar *)x, strlen(x));
	purple_cipher_context_digest(context, sizeof(result), result, NULL);

	a1 = g_strdup_printf("xxxxxxxxxxxxxxxx:%s:%s", nonce, cnonce);
	a1len = strlen(a1);
	g_memmove(a1, result, 16);

	purple_cipher_context_reset(context, NULL);
	purple_cipher_context_append(context, (const guchar *)a1, a1len);
	purple_cipher_context_digest(context, sizeof(result), result, NULL);

	ha1 = purple_base16_encode(result, 16);

	purple_cipher_context_reset(context, NULL);
	purple_cipher_context_append(context, (const guchar *)a2, strlen(a2));
	purple_cipher_context_digest(context, sizeof(result), result, NULL);

	ha2 = purple_base16_encode(result, 16);

	kd = g_strdup_printf("%s:%s:00000001:%s:auth:%s", ha1, nonce, cnonce, ha2);

	purple_cipher_context_reset(context, NULL);
	purple_cipher_context_append(context, (const guchar *)kd, strlen(kd));
	purple_cipher_context_digest(context, sizeof(result), result, NULL);
	purple_cipher_context_destroy(context);

	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;
}
Esempio n. 4
0
static void
cipher_test_aes(void)
{
	PurpleCipher *cipher;
	int i = 0;
	gboolean fail = FALSE;

	purple_debug_info("cipher-test", "Running AES tests\n");

	cipher = purple_aes_cipher_new();
	if (cipher == NULL) {
		purple_debug_error("cipher-test", "AES cipher not found\n");
		fail = TRUE;
	}

	while (!fail && aes_tests[i].cipher) {
		aes_test *test = &aes_tests[i];
		gsize key_size;
		guchar *key;
		guchar cipher_s[1024], decipher_s[1024];
		ssize_t cipher_len, decipher_len;
		gchar *cipher_b16, *deciphered;

		purple_debug_info("cipher-test", "Test %02d:\n", i);
		purple_debug_info("cipher-test", "\tTesting '%s' (%" G_GSIZE_FORMAT "bit) \n",
			test->plaintext ? test->plaintext : "(null)",
			strlen(test->key) * 8 / 2);

		i++;

		purple_cipher_reset(cipher);

		if (test->iv) {
			gsize iv_size;
			guchar *iv = purple_base16_decode(test->iv, &iv_size);
			g_assert(iv != NULL);
			purple_cipher_set_iv(cipher, iv, iv_size);
			g_free(iv);
		}

		key = purple_base16_decode(test->key, &key_size);
		g_assert(key != NULL);
		purple_cipher_set_key(cipher, key, key_size);
		g_free(key);

		if (purple_cipher_get_key_size(cipher) != key_size) {
			purple_debug_info("cipher-test", "\tinvalid key size\n");
			fail = TRUE;
			continue;
		}

		cipher_len = purple_cipher_encrypt(cipher,
			(const guchar*)(test->plaintext ? test->plaintext : ""),
			test->plaintext ? (strlen(test->plaintext) + 1) : 0,
			cipher_s, sizeof(cipher_s));
		if (cipher_len < 0) {
			purple_debug_info("cipher-test", "\tencryption failed\n");
			fail = TRUE;
			continue;
		}

		cipher_b16 = purple_base16_encode(cipher_s, cipher_len);

		purple_debug_info("cipher-test", "\tGot:          %s\n", cipher_b16);
		purple_debug_info("cipher-test", "\tWanted:       %s\n", test->cipher);

		if (g_strcmp0(cipher_b16, test->cipher) != 0) {
			purple_debug_info("cipher-test",
				"\tencrypted data doesn't match\n");
			g_free(cipher_b16);
			fail = TRUE;
			continue;
		}
		g_free(cipher_b16);

		decipher_len = purple_cipher_decrypt(cipher,
			cipher_s, cipher_len, decipher_s, sizeof(decipher_s));
		if (decipher_len < 0) {
			purple_debug_info("cipher-test", "\tdecryption failed\n");
			fail = TRUE;
			continue;
		}

		deciphered = (decipher_len > 0) ? (gchar*)decipher_s : NULL;

		if (g_strcmp0(deciphered, test->plaintext) != 0) {
			purple_debug_info("cipher-test",
				"\tdecrypted data doesn't match\n");
			fail = TRUE;
			continue;
		}

		purple_debug_info("cipher-test", "\tTest OK\n");
	}

	if (cipher != NULL)
		g_object_unref(cipher);

	if (fail)
		purple_debug_info("cipher-test", "AES tests FAILED\n\n");
	else
		purple_debug_info("cipher-test", "AES tests completed successfully\n\n");
}
Esempio n. 5
0
static gchar*
cipher_pbkdf2_nss_sha1(const gchar *passphrase, const gchar *salt,
	guint iter_count, guint out_len)
{
	PK11SlotInfo *slot;
	SECAlgorithmID *algorithm = NULL;
	PK11SymKey *symkey = NULL;
	const SECItem *symkey_data = NULL;
	SECItem salt_item, passphrase_item;
	guchar *passphrase_buff, *salt_buff;
	gchar *ret;

	g_return_val_if_fail(passphrase != NULL, NULL);
	g_return_val_if_fail(iter_count > 0, NULL);
	g_return_val_if_fail(out_len > 0, NULL);

	NSS_NoDB_Init(NULL);

	slot = PK11_GetBestSlot(PK11_AlgtagToMechanism(SEC_OID_PKCS5_PBKDF2),
		NULL);
	if (slot == NULL) {
		purple_debug_error("cipher-test", "NSS: couldn't get slot: "
			"%d\n", PR_GetError());
		return NULL;
	}

	salt_buff = (guchar*)g_strdup(salt ? salt : "");
	salt_item.type = siBuffer;
	salt_item.data = salt_buff;
	salt_item.len = salt ? strlen(salt) : 0;

	algorithm = PK11_CreatePBEV2AlgorithmID(SEC_OID_PKCS5_PBKDF2,
		SEC_OID_AES_256_CBC, SEC_OID_HMAC_SHA1, out_len, iter_count,
		&salt_item);
	if (algorithm == NULL) {
		purple_debug_error("cipher-test", "NSS: couldn't create "
			"algorithm ID: %d\n", PR_GetError());
		PK11_FreeSlot(slot);
		g_free(salt_buff);
		return NULL;
	}

	passphrase_buff = (guchar*)g_strdup(passphrase);
	passphrase_item.type = siBuffer;
	passphrase_item.data = passphrase_buff;
	passphrase_item.len = strlen(passphrase);

	symkey = PK11_PBEKeyGen(slot, algorithm, &passphrase_item, PR_FALSE,
		NULL);
	if (symkey == NULL) {
		purple_debug_error("cipher-test", "NSS: Couldn't generate key: "
			"%d\n", PR_GetError());
		SECOID_DestroyAlgorithmID(algorithm, PR_TRUE);
		PK11_FreeSlot(slot);
		g_free(passphrase_buff);
		g_free(salt_buff);
		return NULL;
	}

	if (PK11_ExtractKeyValue(symkey) == SECSuccess)
		symkey_data = PK11_GetKeyData(symkey);

	if (symkey_data == NULL || symkey_data->data == NULL) {
		purple_debug_error("cipher-test", "NSS: Couldn't extract key "
			"value: %d\n", PR_GetError());
		PK11_FreeSymKey(symkey);
		SECOID_DestroyAlgorithmID(algorithm, PR_TRUE);
		PK11_FreeSlot(slot);
		g_free(passphrase_buff);
		g_free(salt_buff);
		return NULL;
	}

	if (symkey_data->len != out_len) {
		purple_debug_error("cipher-test", "NSS: Invalid key length: %d "
			"(should be %d)\n", symkey_data->len, out_len);
		PK11_FreeSymKey(symkey);
		SECOID_DestroyAlgorithmID(algorithm, PR_TRUE);
		PK11_FreeSlot(slot);
		g_free(passphrase_buff);
		g_free(salt_buff);
		return NULL;
	}

	ret = purple_base16_encode(symkey_data->data, symkey_data->len);

	PK11_FreeSymKey(symkey);
	SECOID_DestroyAlgorithmID(algorithm, PR_TRUE);
	PK11_FreeSlot(slot);
	g_free(passphrase_buff);
	g_free(salt_buff);
	return ret;
}