예제 #1
0
static gchar   *twitter_oauth_sign(const gchar * txt, const gchar * key)
{
    PurpleCipher   *cipher;
    PurpleCipherContext *ctx;
    static guchar   output[20];
    size_t          output_size;

    cipher = purple_ciphers_find_cipher("hmac");
    if (!cipher) {
        purple_debug_error(GENERIC_PROTOCOL_ID, "%s: Could not find cipher\n", G_STRFUNC);
        return NULL;
    }
    ctx = purple_cipher_context_new(cipher, NULL);
    if (!ctx) {
        purple_debug_error(GENERIC_PROTOCOL_ID, "%s: Could not create cipher context\n", G_STRFUNC);
        return NULL;
    }
    purple_cipher_context_set_option(ctx, "hash", "sha1");

    purple_cipher_context_set_key(ctx, (guchar *) key);
    purple_cipher_context_append(ctx, (guchar *) txt, strlen(txt));
    if (!purple_cipher_context_digest(ctx, 20, output, &output_size)) {
        purple_debug_error(GENERIC_PROTOCOL_ID, "%s: Could not sign text\n", G_STRFUNC);
        purple_cipher_context_destroy(ctx);
        return NULL;
    }
    purple_cipher_context_destroy(ctx);
    return purple_base64_encode(output, output_size);

}
예제 #2
0
파일: cipher.c 프로젝트: CkNoSFeRaTU/pidgin
gboolean
purple_cipher_digest_region(const gchar *name, const guchar *data,
						  size_t data_len, size_t in_len,
						  guchar digest[], size_t *out_len)
{
	PurpleCipher *cipher;
	PurpleCipherContext *context;
	gboolean ret = FALSE;

	g_return_val_if_fail(name, FALSE);
	g_return_val_if_fail(data, FALSE);

	cipher = purple_ciphers_find_cipher(name);

	g_return_val_if_fail(cipher, FALSE);

	if(!cipher->ops->append || !cipher->ops->digest) {
		purple_debug_warning("cipher", "purple_cipher_region failed: "
						"the %s cipher does not support appending and or "
						"digesting.", cipher->name);
		return FALSE;
	}

	context = purple_cipher_context_new(cipher, NULL);
	purple_cipher_context_append(context, data, data_len);
	ret = purple_cipher_context_digest(context, in_len, digest, out_len);
	purple_cipher_context_destroy(context);

	return ret;
}
예제 #3
0
파일: cipher.c 프로젝트: CkNoSFeRaTU/pidgin
PurpleCipherContext *
purple_cipher_context_new_by_name(const gchar *name, void *extra) {
	PurpleCipher *cipher;

	g_return_val_if_fail(name, NULL);

	cipher = purple_ciphers_find_cipher(name);

	g_return_val_if_fail(cipher, NULL);

	return purple_cipher_context_new(cipher, extra);
}
예제 #4
0
static void
msn_dc_calculate_nonce_hash(MsnDirectConnNonceType type,
                            const guchar *nonce, gsize nonce_len, gchar nonce_hash[37])
{
	guchar digest[20];

	if (type == DC_NONCE_SHA1) {
		PurpleCipher *cipher = purple_ciphers_find_cipher("sha1");
		PurpleCipherContext *context = purple_cipher_context_new(cipher, NULL);
		purple_cipher_context_append(context, nonce, nonce_len);
		purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
		purple_cipher_context_destroy(context);
	} else if (type == DC_NONCE_PLAIN) {
		memcpy(digest, nonce, nonce_len);
	} else {
		nonce_hash[0] = '\0';
		g_return_if_reached();
	}

	g_sprintf(nonce_hash,
	          "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",

	          digest[3],
	          digest[2],
	          digest[1],
	          digest[0],

	          digest[5],
	          digest[4],

	          digest[7],
	          digest[6],

	          digest[8],
	          digest[9],

	          digest[10],
	          digest[11],
	          digest[12],
	          digest[13],
	          digest[14],
	          digest[15]
	);
}
예제 #5
0
char  *crypt_pass(char *password)
{
  unsigned char	pass[16];
  char		*out;
  size_t	len;
  PurpleCipher *md5;
  PurpleCipherContext *context;

  md5 = purple_ciphers_find_cipher ("md5");
  context = purple_cipher_context_new (md5, NULL);
  purple_cipher_context_append (context, (const guchar *)password, strlen (password));
  purple_cipher_context_digest (context, strlen (password), pass, &len);
  purple_cipher_context_destroy (context);

  out = g_strdup_printf("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
			pass[0],pass[1],pass[2],pass[3],pass[4],pass[5],pass[6],pass[7],pass[8],
			pass[9],pass[10],pass[11],pass[12],pass[13],pass[14],pass[15]);
  return (out);
}
예제 #6
0
파일: cipher.c 프로젝트: CkNoSFeRaTU/pidgin
PurpleCipher *
purple_ciphers_register_cipher(const gchar *name, PurpleCipherOps *ops) {
	PurpleCipher *cipher = NULL;

	g_return_val_if_fail(name, NULL);
	g_return_val_if_fail(ops, NULL);
	g_return_val_if_fail(!purple_ciphers_find_cipher(name), NULL);

	cipher = g_new0(PurpleCipher, 1);
	PURPLE_DBUS_REGISTER_POINTER(cipher, PurpleCipher);

	cipher->name = g_strdup(name);
	cipher->ops = ops;

	ciphers = g_list_append(ciphers, cipher);

	purple_signal_emit(purple_ciphers_get_handle(), "cipher-added", cipher);

	return cipher;
}
예제 #7
0
static void
chl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
    MsnTransaction *trans;
    gchar buf[32];

#if 0
    PurpleCipher *cipher;
    PurpleCipherContext *context;
    guchar digest[16];
    const char *challenge_resp;
    int i;

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

    purple_cipher_context_append(context, (const guchar *)cmd->params[1],
                                 strlen(cmd->params[1]));

    challenge_resp = "VT6PX?UQTM4WM%YR";

    purple_cipher_context_append(context, (const guchar *)challenge_resp,
                                 strlen(challenge_resp));
    purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
    purple_cipher_context_destroy(context);

    for (i = 0; i < 16; i++)
        g_snprintf(buf + (i*2), 3, "%02x", digest[i]);
#else
    pecan_handle_challenge (cmd->params[1], "PROD0101{0RM?UBW", buf);
#endif

    /* trans = msn_transaction_new(cmdproc, "QRY", "%s 32", "PROD0038W!61ZTF9"); */
    trans = msn_transaction_new (cmdproc, "QRY", "%s 32", "PROD0101{0RM?UBW");

    msn_transaction_set_payload (trans, buf, 32);

    msn_cmdproc_send_trans (cmdproc, trans);
}
예제 #8
0
static int
aim_encode_password_md5(const char *password, size_t password_len, const char *key, guint8 *digest)
{
	PurpleCipher *cipher;
	PurpleCipherContext *context;
	guchar passdigest[16];

	cipher = purple_ciphers_find_cipher("md5");

	context = purple_cipher_context_new(cipher, NULL);
	purple_cipher_context_append(context, (const guchar *)password, password_len);
	purple_cipher_context_digest(context, 16, passdigest, NULL);
	purple_cipher_context_destroy(context);

	context = purple_cipher_context_new(cipher, NULL);
	purple_cipher_context_append(context, (const guchar *)key, strlen(key));
	purple_cipher_context_append(context, passdigest, 16);
	purple_cipher_context_append(context, (const guchar *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));
	purple_cipher_context_digest(context, 16, digest, NULL);
	purple_cipher_context_destroy(context);

	return 0;
}
예제 #9
0
파일: f_util.c 프로젝트: scljz/fetion
gchar *fetion_cipher_digest_calculate_response(
		const gchar *sid,
		const gchar *domain,
		const gchar *password,
		const gchar *nonce,
		const gchar *cnonce)
{
	PurpleCipher *cipher;
	PurpleCipherContext *context;
	gchar *hash1; /* We only support MD5. */
	gchar *hash2; /* We only support MD5. */
	gchar temp[33];
	gchar *response; /* We only support MD5. */
	guchar digest[16];

	g_return_val_if_fail(sid != NULL, NULL);
	g_return_val_if_fail(domain    != NULL, NULL);
	g_return_val_if_fail(password != NULL, NULL);
	g_return_val_if_fail(nonce    != NULL, NULL);
	g_return_val_if_fail(cnonce    != NULL, NULL);


	cipher = purple_ciphers_find_cipher("md5");
	g_return_val_if_fail(cipher != NULL, NULL);

	context = purple_cipher_context_new(cipher, NULL);

	purple_cipher_context_append(context, (guchar *)sid, strlen(sid));
	purple_cipher_context_append(context, (guchar *)":", 1);
	purple_cipher_context_append(context, (guchar *)domain, strlen(domain));
	purple_cipher_context_append(context, (guchar *)":", 1);
	purple_cipher_context_append(context, (guchar *)password, strlen(password));

	purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
	purple_cipher_context_destroy(context);

	context = purple_cipher_context_new(cipher, NULL);
	purple_cipher_context_append(context, digest, 16);
	purple_cipher_context_append(context, (guchar *)":", 1);
	purple_cipher_context_append(context, (guchar *)nonce, strlen(nonce));
	purple_cipher_context_append(context, (guchar *)":", 1);
	purple_cipher_context_append(context, (guchar *)cnonce, strlen(cnonce));
	purple_cipher_context_digest_to_str(context, sizeof(temp), temp, NULL);
	purple_cipher_context_destroy(context);
	hash1=g_ascii_strup(temp,32);


	context = purple_cipher_context_new(cipher, NULL);
	purple_cipher_context_append(context,(guchar *)"REGISTER",8 );
	purple_cipher_context_append(context,(guchar *)":",1 );
	purple_cipher_context_append(context,(guchar *)sid, strlen(sid) );
	purple_cipher_context_digest_to_str(context, sizeof(temp), temp, NULL);

	hash2=g_ascii_strup(temp,32);

	purple_cipher_context_destroy(context);
	context = purple_cipher_context_new(cipher, NULL);
	purple_cipher_context_append(context,(guchar *)hash1,strlen(hash1) );
	purple_cipher_context_append(context,(guchar *)":",1 );
	purple_cipher_context_append(context, (guchar *)nonce, strlen(nonce));
	purple_cipher_context_append(context,(guchar *)":",1 );
	purple_cipher_context_append(context,(guchar *)hash2,strlen(hash2) );
	purple_cipher_context_digest_to_str(context, sizeof(temp), temp, NULL);
	purple_cipher_context_destroy(context);

	response=g_ascii_strup(temp,32);
	return g_strdup(response);
}
예제 #10
0
static void
url_cmd (MsnCmdProc *cmdproc,
         MsnCommand *cmd)
{
    MsnSession *session;
    PurpleConnection *connection;
    const gchar *rru;
    const gchar *url;
    gchar creds[64];
    glong tmp_timestamp;

    session = cmdproc->session;
    connection = purple_account_get_connection (session->account);

    rru = cmd->params[1];
    url = cmd->params[2];

    session->passport_info.mail_url_timestamp = time (NULL);
    tmp_timestamp = session->passport_info.mail_url_timestamp - session->passport_info.sl;

    {
        PurpleCipher *cipher;
        PurpleCipherContext *context;
        guchar digest[16];
        gchar *buf;

        buf = pecan_strdup_printf ("%s%ld%s",
                                   session->passport_info.mspauth ? session->passport_info.mspauth : "BOGUS",
                                   tmp_timestamp,
                                   purple_connection_get_password (connection));

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

        purple_cipher_context_append (context, (const guchar *) buf, strlen (buf));
        purple_cipher_context_digest (context, sizeof (digest), digest, NULL);
        purple_cipher_context_destroy (context);

        g_free (buf);

        memset (creds, 0, sizeof (creds));

        {
            gchar buf2[3];
            gint i;

            for (i = 0; i < 16; i++)
            {
                g_snprintf (buf2, sizeof (buf2), "%02x", digest[i]);
                strcat (creds, buf2);
            }
        }
    }

    g_free (session->passport_info.mail_url);

    session->passport_info.mail_url = g_strdup_printf ("%s&auth=%s&creds=%s&sl=%ld&username=%s&mode=ttl&sid=%s&id=2&rru=%ssvc_mail&js=yes",
                                                       url,
                                                       session->passport_info.mspauth,
                                                       creds,
                                                       tmp_timestamp,
                                                       msn_session_get_username (session),
                                                       session->passport_info.sid,
                                                       rru);

    /* The user wants to check his email */
    if (cmd->trans && cmd->trans->data)
    {
        purple_notify_uri (connection, session->passport_info.mail_url);
        return;
    }

    if (purple_account_get_check_mail (session->account))
    {
        static gboolean is_initial = TRUE;

        if (!is_initial)
            return;

        if (session->inbox_unread_count > 0)
        {
            const gchar *passport;
            const gchar *main_url;

            passport = msn_session_get_username (session);
            main_url = session->passport_info.mail_url;

            purple_notify_emails (connection, session->inbox_unread_count, FALSE, NULL, NULL,
                                  &passport, &main_url, NULL, NULL);
        }

        is_initial = FALSE;
    }
}
예제 #11
0
void
msn_handle_chl(char *input, char *output)
{
	PurpleCipher *cipher;
	PurpleCipherContext *context;
	const guchar productKey[] = MSNP15_WLM_PRODUCT_KEY;
	const guchar productID[]  = MSNP15_WLM_PRODUCT_ID;
	const char hexChars[]     = "0123456789abcdef";
	char buf[BUFSIZE];
	unsigned char md5Hash[16];
	unsigned char *newHash;
	unsigned int *md5Parts;
	unsigned int *chlStringParts;
	unsigned int newHashParts[5];

	long long nHigh = 0, nLow = 0;

	int len;
	int i;

	/* Create the MD5 hash by using Purple MD5 algorithm */
	cipher = purple_ciphers_find_cipher("md5");
	context = purple_cipher_context_new(cipher, NULL);

	purple_cipher_context_append(context, (guchar *)input, strlen(input));
	purple_cipher_context_append(context, productKey, sizeof(productKey) - 1);
	purple_cipher_context_digest(context, sizeof(md5Hash), md5Hash, NULL);
	purple_cipher_context_destroy(context);

	/* Split it into four integers */
	md5Parts = (unsigned int *)md5Hash;
	for (i = 0; i < 4; i++) {
		/* adjust endianess */
		md5Parts[i] = GUINT_TO_LE(md5Parts[i]);

		/* & each integer with 0x7FFFFFFF          */
		/* and save one unmodified array for later */
		newHashParts[i] = md5Parts[i];
		md5Parts[i] &= 0x7FFFFFFF;
	}

	/* make a new string and pad with '0' to length that's a multiple of 8 */
	snprintf(buf, BUFSIZE - 5, "%s%s", input, productID);
	len = strlen(buf);
	if ((len % 8) != 0) {
		int fix = 8 - (len % 8);
		memset(&buf[len], '0', fix);
		buf[len + fix] = '\0';
		len += fix;
	}

	/* split into integers */
	chlStringParts = (unsigned int *)buf;

	/* this is magic */
	for (i = 0; i < (len / 4); i += 2) {
		long long temp;

		chlStringParts[i] = GUINT_TO_LE(chlStringParts[i]);
		chlStringParts[i + 1] = GUINT_TO_LE(chlStringParts[i + 1]);

		temp = (0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF;
		temp = (md5Parts[0] * (temp + nLow) + md5Parts[1]) % 0x7FFFFFFF;
		nHigh += temp;

		temp = ((long long)chlStringParts[i + 1] + temp) % 0x7FFFFFFF;
		nLow = (md5Parts[2] * temp + md5Parts[3]) % 0x7FFFFFFF;
		nHigh += nLow;
	}
	nLow = (nLow + md5Parts[1]) % 0x7FFFFFFF;
	nHigh = (nHigh + md5Parts[3]) % 0x7FFFFFFF;

	newHashParts[0] ^= nLow;
	newHashParts[1] ^= nHigh;
	newHashParts[2] ^= nLow;
	newHashParts[3] ^= nHigh;

	/* adjust endianness */
	for(i = 0; i < 4; i++)
		newHashParts[i] = GUINT_TO_LE(newHashParts[i]);

	/* make a string of the parts */
	newHash = (unsigned char *)newHashParts;

	/* convert to hexadecimal */
	for (i = 0; i < 16; i++)
	{
		output[i * 2] = hexChars[(newHash[i] >> 4) & 0xF];
		output[(i * 2) + 1] = hexChars[newHash[i] & 0xF];
	}

	output[32] = '\0';
}
예제 #12
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;
}
예제 #13
0
char *yahoo_crypt(const char *key, const char *salt)
{
	PurpleCipher *cipher;
	PurpleCipherContext *context1, *context2;
	guchar digest[16];
	static char *buffer = NULL;
	static int buflen = 0;
	int needed = 3 + strlen (salt) + 1 + 26 + 1;

	size_t salt_len;
	size_t key_len;
	size_t cnt;

	char *cp;

	if (buflen < needed) {
		buflen = needed;
		if ((buffer = g_realloc(buffer, buflen)) == NULL)
			return NULL;
	}

	cipher = purple_ciphers_find_cipher("md5");
	context1 = purple_cipher_context_new(cipher, NULL);
	context2 = purple_cipher_context_new(cipher, NULL);

	/* Find beginning of salt string.  The prefix should normally always
	 * be present.  Just in case it is not.
	 */
	if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
		/* Skip salt prefix.  */
		salt += sizeof (md5_salt_prefix) - 1;

	salt_len = MIN (strcspn (salt, "$"), 8);
	key_len = strlen (key);

	/* Add the key string.  */
	purple_cipher_context_append(context1, (const guchar *)key, key_len);

	/* Because the SALT argument need not always have the salt prefix we
	 * add it separately.
	 */
	purple_cipher_context_append(context1, (const guchar *)md5_salt_prefix,
							   sizeof(md5_salt_prefix) - 1);

	/* The last part is the salt string.  This must be at most 8
	 * characters and it ends at the first `$' character (for
	 * compatibility which existing solutions).
	 */
	purple_cipher_context_append(context1, (const guchar *)salt, salt_len);

	/* Compute alternate MD5 sum with input KEY, SALT, and KEY.  The
	 * final result will be added to the first context.
	 */

	/* Add key.  */
	purple_cipher_context_append(context2, (const guchar *)key, key_len);

	/* Add salt.  */
	purple_cipher_context_append(context2, (const guchar *)salt, salt_len);

	/* Add key again.  */
	purple_cipher_context_append(context2, (const guchar *)key, key_len);

	/* Now get result of this (16 bytes) and add it to the other context.  */
	purple_cipher_context_digest(context2, sizeof(digest), digest, NULL);

	/* Add for any character in the key one byte of the alternate sum.  */
	for (cnt = key_len; cnt > 16; cnt -= 16)
		purple_cipher_context_append(context1, digest, 16);
	purple_cipher_context_append(context1, digest, cnt);

	/* For the following code we need a NUL byte.  */
	digest[0] = '\0';

	/* The original implementation now does something weird: for every 1
	 * bit in the key the first 0 is added to the buffer, for every 0
	 * bit the first character of the key.  This does not seem to be
	 * what was intended but we have to follow this to be compatible.
	 */
	for (cnt = key_len; cnt > 0; cnt >>= 1)
		purple_cipher_context_append(context1,
								   (cnt & 1) != 0 ? digest : (guchar *)key, 1);

	/* Create intermediate result.  */
	purple_cipher_context_digest(context1, sizeof(digest), digest, NULL);

	/* Now comes another weirdness.  In fear of password crackers here
	 * comes a quite long loop which just processes the output of the
	 * previous round again.  We cannot ignore this here.
	 */
	for (cnt = 0; cnt < 1000; ++cnt) {
		/* New context.  */
		purple_cipher_context_reset(context2, NULL);

		/* Add key or last result.  */
		if ((cnt & 1) != 0)
			purple_cipher_context_append(context2, (const guchar *)key, key_len);
		else
			purple_cipher_context_append(context2, digest, 16);

		/* Add salt for numbers not divisible by 3.  */
		if (cnt % 3 != 0)
			purple_cipher_context_append(context2, (const guchar *)salt, salt_len);

		/* Add key for numbers not divisible by 7.  */
		if (cnt % 7 != 0)
			purple_cipher_context_append(context2, (const guchar *)key, key_len);

		/* Add key or last result.  */
		if ((cnt & 1) != 0)
			purple_cipher_context_append(context2, digest, 16);
		else
			purple_cipher_context_append(context2, (const guchar *)key, key_len);

		/* Create intermediate result.  */
		purple_cipher_context_digest(context2, sizeof(digest), digest, NULL);
	}

	/* Now we can construct the result string.  It consists of three parts. */
	strncpy(buffer, md5_salt_prefix, MAX (0, buflen));
	cp = buffer + strlen(buffer);
	buflen -= sizeof (md5_salt_prefix);

	strncpy(cp, salt, MIN ((size_t) buflen, salt_len));
	cp = cp + strlen(cp);
	buflen -= MIN ((size_t) buflen, salt_len);

	if (buflen > 0) {
		*cp++ = '$';
		--buflen;
	}

#define b64_from_24bit(B2, B1, B0, N) \
	do { \
		unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
		int n = (N); \
		while (n-- > 0 && buflen > 0) { \
			*cp++ = b64t[w & 0x3f]; \
			--buflen; \
			w >>= 6; \
		}\
	} while (0)

	b64_from_24bit (digest[0], digest[6], digest[12], 4);
	b64_from_24bit (digest[1], digest[7], digest[13], 4);
	b64_from_24bit (digest[2], digest[8], digest[14], 4);
	b64_from_24bit (digest[3], digest[9], digest[15], 4);
	b64_from_24bit (digest[4], digest[10], digest[5], 4);
	b64_from_24bit (0, 0, digest[11], 2);
	if (buflen <= 0) {
		g_free(buffer);
		buffer = NULL;
	} else
		*cp = '\0';	/* Terminate the string.  */

	/* Clear the buffer for the intermediate result so that people
	 * attaching to processes or reading core dumps cannot get any
	 * information.  We do it in this way to clear correct_words[]
	 * inside the MD5 implementation as well.
	 */
	purple_cipher_context_reset(context1, NULL);
	purple_cipher_context_digest(context1, sizeof(digest), digest, NULL);
	purple_cipher_context_destroy(context1);
	purple_cipher_context_destroy(context2);

	return buffer;
}
예제 #14
0
파일: cipher.c 프로젝트: CkNoSFeRaTU/pidgin
gchar *purple_cipher_http_digest_calculate_response(
		const gchar *algorithm,
		const gchar *method,
		const gchar *digest_uri,
		const gchar *qop,
		const gchar *entity,
		const gchar *nonce,
		const gchar *nonce_count,
		const gchar *client_nonce,
		const gchar *session_key)
{
	PurpleCipher *cipher;
	PurpleCipherContext *context;
	static gchar hash2[33]; /* We only support MD5. */

	g_return_val_if_fail(method      != NULL, NULL);
	g_return_val_if_fail(digest_uri  != NULL, NULL);
	g_return_val_if_fail(nonce       != NULL, NULL);
	g_return_val_if_fail(session_key != NULL, NULL);

	/* Check for a supported algorithm. */
	g_return_val_if_fail(algorithm == NULL ||
						 *algorithm == '\0' ||
						 g_ascii_strcasecmp(algorithm, "MD5") ||
						 g_ascii_strcasecmp(algorithm, "MD5-sess"), NULL);

	/* Check for a supported "quality of protection". */
	g_return_val_if_fail(qop == NULL ||
						 *qop == '\0' ||
						 g_ascii_strcasecmp(qop, "auth") ||
						 g_ascii_strcasecmp(qop, "auth-int"), NULL);

	cipher = purple_ciphers_find_cipher("md5");
	g_return_val_if_fail(cipher != NULL, NULL);

	context = purple_cipher_context_new(cipher, NULL);

	purple_cipher_context_append(context, (guchar *)method, strlen(method));
	purple_cipher_context_append(context, (guchar *)":", 1);
	purple_cipher_context_append(context, (guchar *)digest_uri, strlen(digest_uri));

	if (qop != NULL && !g_ascii_strcasecmp(qop, "auth-int"))
	{
		PurpleCipherContext *context2;
		gchar entity_hash[33];

		if (entity == NULL)
		{
			purple_cipher_context_destroy(context);
			purple_debug_error("cipher", "Required entity missing for auth-int digest calculation.\n");
			return NULL;
		}

		context2 = purple_cipher_context_new(cipher, NULL);
		purple_cipher_context_append(context2, (guchar *)entity, strlen(entity));
		purple_cipher_context_digest_to_str(context2, sizeof(entity_hash), entity_hash, NULL);
		purple_cipher_context_destroy(context2);

		purple_cipher_context_append(context, (guchar *)":", 1);
		purple_cipher_context_append(context, (guchar *)entity_hash, strlen(entity_hash));
	}

	purple_cipher_context_digest_to_str(context, sizeof(hash2), hash2, NULL);
	purple_cipher_context_destroy(context);

	context = purple_cipher_context_new(cipher, NULL);
	purple_cipher_context_append(context, (guchar *)session_key, strlen(session_key));
	purple_cipher_context_append(context, (guchar *)":", 1);
	purple_cipher_context_append(context, (guchar *)nonce, strlen(nonce));
	purple_cipher_context_append(context, (guchar *)":", 1);

	if (qop != NULL && *qop != '\0')
	{
		if (nonce_count == NULL)
		{
			purple_cipher_context_destroy(context);
			purple_debug_error("cipher", "Required nonce_count missing for digest calculation.\n");
			return NULL;
		}

		if (client_nonce == NULL)
		{
			purple_cipher_context_destroy(context);
			purple_debug_error("cipher", "Required client_nonce missing for digest calculation.\n");
			return NULL;
		}

		purple_cipher_context_append(context, (guchar *)nonce_count, strlen(nonce_count));
		purple_cipher_context_append(context, (guchar *)":", 1);
		purple_cipher_context_append(context, (guchar *)client_nonce, strlen(client_nonce));
		purple_cipher_context_append(context, (guchar *)":", 1);

		purple_cipher_context_append(context, (guchar *)qop, strlen(qop));

		purple_cipher_context_append(context, (guchar *)":", 1);
	}

	purple_cipher_context_append(context, (guchar *)hash2, strlen(hash2));
	purple_cipher_context_digest_to_str(context, sizeof(hash2), hash2, NULL);
	purple_cipher_context_destroy(context);

	return g_strdup(hash2);
}
예제 #15
0
파일: cipher.c 프로젝트: CkNoSFeRaTU/pidgin
gchar *purple_cipher_http_digest_calculate_session_key(
		const gchar *algorithm,
		const gchar *username,
		const gchar *realm,
		const gchar *password,
		const gchar *nonce,
		const gchar *client_nonce)
{
	PurpleCipher *cipher;
	PurpleCipherContext *context;
	gchar hash[33]; /* We only support MD5. */

	g_return_val_if_fail(username != NULL, NULL);
	g_return_val_if_fail(realm    != NULL, NULL);
	g_return_val_if_fail(password != NULL, NULL);
	g_return_val_if_fail(nonce    != NULL, NULL);

	/* Check for a supported algorithm. */
	g_return_val_if_fail(algorithm == NULL ||
						 *algorithm == '\0' ||
						 g_ascii_strcasecmp(algorithm, "MD5") ||
						 g_ascii_strcasecmp(algorithm, "MD5-sess"), NULL);

	cipher = purple_ciphers_find_cipher("md5");
	g_return_val_if_fail(cipher != NULL, NULL);

	context = purple_cipher_context_new(cipher, NULL);

	purple_cipher_context_append(context, (guchar *)username, strlen(username));
	purple_cipher_context_append(context, (guchar *)":", 1);
	purple_cipher_context_append(context, (guchar *)realm, strlen(realm));
	purple_cipher_context_append(context, (guchar *)":", 1);
	purple_cipher_context_append(context, (guchar *)password, strlen(password));

	if (algorithm != NULL && !g_ascii_strcasecmp(algorithm, "MD5-sess"))
	{
		guchar digest[16];

		if (client_nonce == NULL)
		{
			purple_cipher_context_destroy(context);
			purple_debug_error("cipher", "Required client_nonce missing for MD5-sess digest calculation.\n");
			return NULL;
		}

		purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
		purple_cipher_context_destroy(context);

		context = purple_cipher_context_new(cipher, NULL);
		purple_cipher_context_append(context, digest, sizeof(digest));
		purple_cipher_context_append(context, (guchar *)":", 1);
		purple_cipher_context_append(context, (guchar *)nonce, strlen(nonce));
		purple_cipher_context_append(context, (guchar *)":", 1);
		purple_cipher_context_append(context, (guchar *)client_nonce, strlen(client_nonce));
	}

	purple_cipher_context_digest_to_str(context, sizeof(hash), hash, NULL);
	purple_cipher_context_destroy(context);

	return g_strdup(hash);
}