コード例 #1
0
static void
msn_dc_send_handshake(MsnDirectConn *dc)
{
	MsnDirectConnPacket *p;
	gchar *h;

	p = msn_dc_new_packet(DC_NONCE_PACKET_SIZE);
	h = (gchar *)p->data;

	msn_push32le(h, 0); /* NUL */

	msn_push32le(h, dc->slpcall->slplink->slp_seq_id++);

	/* More NUL stuff */
	msn_push64le(h, 0);
	msn_push64le(h, 0);
	msn_push32le(h, 0);

	/* Flags */
	msn_push32le(h, P2P_DC_HANDSHAKE);

	/* The real Nonce, yay! */
	memcpy(h, dc->nonce, 16);

	msn_dc_enqueue_packet(dc, p);
}
コード例 #2
0
ファイル: nexus.c プロジェクト: Lilitana/Pidgin
static char *
msn_rps_encrypt(MsnNexus *nexus)
{
	char usr_key_base[MSN_USER_KEY_SIZE], *usr_key;
	const char magic1[] = "SESSION KEY HASH";
	const char magic2[] = "SESSION KEY ENCRYPTION";
	PurpleCipherContext *hmac;
	size_t len;
	guchar *hash;
	char *key1, *key2, *key3;
	gsize key1_len;
	const char *iv;
	char *nonce_fixed;
	char *cipher;
	char *response;

	usr_key = &usr_key_base[0];
	/* Header */
	msn_push32le(usr_key, 28);                  /* Header size */
	msn_push32le(usr_key, CRYPT_MODE_CBC);      /* Crypt mode */
	msn_push32le(usr_key, CIPHER_TRIPLE_DES);   /* Cipher type */
	msn_push32le(usr_key, HASH_SHA1);           /* Hash type */
	msn_push32le(usr_key, 8);                   /* IV size */
	msn_push32le(usr_key, 20);                  /* Hash size */
	msn_push32le(usr_key, 72);                  /* Cipher size */
	/* Data */
	iv = usr_key;
	msn_push32le(usr_key, rand());
	msn_push32le(usr_key, rand());
	hash = (guchar *)usr_key;
	usr_key += 20;  /* Remaining is cipher data */

	key1 = (char *)purple_base64_decode((const char *)nexus->tokens[MSN_AUTH_MESSENGER].secret, &key1_len);
	key2 = rps_create_key(key1, key1_len, magic1, sizeof(magic1) - 1);
	key3 = rps_create_key(key1, key1_len, magic2, sizeof(magic2) - 1);

	len = strlen(nexus->nonce);
	hmac = purple_cipher_context_new_by_name("hmac", NULL);
	purple_cipher_context_set_option(hmac, "hash", "sha1");
	purple_cipher_context_set_key_with_len(hmac, (guchar *)key2, 24);
	purple_cipher_context_append(hmac, (guchar *)nexus->nonce, len);
	purple_cipher_context_digest(hmac, 20, hash, NULL);
	purple_cipher_context_destroy(hmac);

	/* We need to pad this to 72 bytes, apparently */
	nonce_fixed = g_malloc(len + 8);
	memcpy(nonce_fixed, nexus->nonce, len);
	memset(nonce_fixed + len, 0x08, 8);
	cipher = des3_cbc(key3, iv, nonce_fixed, len + 8, FALSE);
	g_free(nonce_fixed);

	memcpy(usr_key, cipher, 72);

	g_free(key1);
	g_free(key2);
	g_free(key3);
	g_free(cipher);

	response = purple_base64_encode((guchar *)usr_key_base, MSN_USER_KEY_SIZE);

	return response;
}