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; }
/** * @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)); }
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; }
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"); }
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; }