static void silcpurple_buddy_privkey_cb(SilcPurplePrivkey p, const char *passphrase) { SilcClientEntry client_entry; if (!passphrase || !(*passphrase)) { silc_free(p); return; } /* Get the client entry. */ client_entry = silc_client_get_client_by_id(p->client, p->conn, &p->client_id); if (!client_entry) { purple_notify_error(p->client->application, _("IM With Password"), _("The remote user is not present in the network any more"), NULL); silc_free(p); return; } /* Set the private message key */ silc_client_del_private_message_key(p->client, p->conn, client_entry); silc_client_add_private_message_key(p->client, p->conn, client_entry, NULL, NULL, (unsigned char *)passphrase, strlen(passphrase), FALSE, client_entry->prv_resp); if (!client_entry->prv_resp) silc_client_send_private_message_key_request(p->client, p->conn, client_entry); silc_free(p); }
SilcBool silc_client_add_private_message_key(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, const char *cipher, const char *hmac, unsigned char *key, SilcUInt32 key_len) { SilcSKEKeyMaterial keymat; SilcBool ret; if (!client || !client_entry) return FALSE; /* Return FALSE if key already set */ if (client_entry->internal.send_key && client_entry->internal.receive_key) return FALSE; if (!cipher) cipher = SILC_DEFAULT_CIPHER; if (!hmac) hmac = SILC_DEFAULT_HMAC; /* Check the requested cipher and HMAC */ if (!silc_cipher_is_supported(cipher)) return FALSE; if (!silc_hmac_is_supported(hmac)) return FALSE; /* Save the key */ client_entry->internal.key = silc_memdup(key, key_len); client_entry->internal.key_len = key_len; /* Produce the key material as the protocol defines */ keymat = silc_ske_process_key_material_data(key, key_len, 16, 256, 16, conn->internal->sha1hash); if (!keymat) return FALSE; /* Set the key into use */ ret = silc_client_add_private_message_key_ske(client, conn, client_entry, cipher, hmac, keymat); client_entry->internal.generated = FALSE; /* Free the key material */ silc_ske_free_key_material(keymat); /* If we are setting the key without a request from the remote client, we will send request to remote. */ if (!client_entry->internal.prv_resp) silc_client_send_private_message_key_request(client, conn, client_entry); return ret; }