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); }
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; }