SilcSocketConnection sock = conn->sock;
SilcBuffer buffer;
SilcPacketContext packetdata;
+ const SilcBufferStruct packet;
SilcCipher cipher;
SilcHmac hmac;
int block_len;
/* We have private message specific key */
/* Get data used in the encryption */
- cipher = client_entry->send_key;
+ cipher = conn->send_key;
hmac = conn->hmac_send;
block_len = silc_cipher_get_block_len(cipher);
packetdata.src_id_len +
packetdata.dst_id_len), block_len);
- /* Prepare outgoing data buffer for packet sending */
- silc_packet_send_prepare(sock,
- SILC_PACKET_HEADER_LEN +
- packetdata.src_id_len +
- packetdata.dst_id_len,
- packetdata.padlen,
- data_len);
-
- packetdata.buffer = sock->outbuf;
-
- /* Put the actual encrypted message payload data into the buffer. */
- silc_buffer_put(sock->outbuf, data, data_len);
-
/* Create the outgoing packet */
- silc_packet_assemble(&packetdata, cipher);
+ if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
+ data, data_len, (const SilcBuffer)&packet)) {
+ SILC_LOG_ERROR(("Error assembling packet"));
+ goto out;
+ }
/* Encrypt the header and padding of the packet. */
- cipher = conn->send_key;
silc_packet_encrypt(cipher, hmac, conn->psn_send++,
- sock->outbuf, SILC_PACKET_HEADER_LEN +
+ (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN +
packetdata.src_id_len + packetdata.dst_id_len +
packetdata.padlen);
- SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
- sock->outbuf->data, sock->outbuf->len);
+ SILC_LOG_HEXDUMP(("Private message packet, len %d", packet.len),
+ packet.data, packet.len);
/* Now actually send the packet */
silc_client_packet_send_real(client, sock, force_send);
SilcClientID *remote_id = NULL;
SilcClientEntry remote_client;
SilcMessageFlags flags;
+ unsigned char *message;
+ SilcUInt32 message_len;
+ SilcCipher cipher = NULL;
if (packet->src_id_type != SILC_ID_CLIENT)
goto out;
goto out;
}
remote_client->status |= SILC_CLIENT_STATUS_RESOLVING;
+ remote_client->resolve_cmd_ident = conn->cmd_ident + 1;
}
/* Resolve the client info */
- silc_client_get_client_by_id_resolve(client, conn, remote_id,
+ silc_client_get_client_by_id_resolve(client, conn, remote_id, NULL,
silc_client_private_message_cb,
silc_packet_context_dup(packet));
return;
}
+ cipher = remote_client->receive_key;
+ if (packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY && !cipher) {
+ silc_free(remote_id);
+ return;
+ }
+
/* Parse the payload and decrypt it also if private message key is set */
payload = silc_private_message_payload_parse(packet->buffer->data,
- packet->buffer->len,
- remote_client->receive_key);
+ packet->buffer->len, cipher);
if (!payload) {
silc_free(remote_id);
return;
flags = silc_private_message_get_flags(payload);
/* Pass the private message to application */
- client->internal->ops->private_message(
- client, conn, remote_client, flags,
- silc_private_message_get_message(payload,
- NULL));
+ message = silc_private_message_get_message(payload, &message_len);
+ client->internal->ops->private_message(client, conn, remote_client, flags,
+ message, message_len);
/* See if we are away (gone). If we are away we will reply to the
sender with the set away message. */
return;
silc_client_get_client_by_id_resolve(client, sock->user_data, remote_id,
+ NULL,
silc_client_private_message_key_cb,
silc_packet_context_dup(packet));
silc_free(remote_id);