5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
20 /* Includes the Private Message Payload implementation */
23 #include "silcincludes.h"
24 #include "silcprivate.h"
26 /******************************************************************************
28 Private Message Payload
30 ******************************************************************************/
32 /* Private Message Payload structure. Contents of this structure is parsed
34 struct SilcPrivateMessagePayloadStruct {
36 unsigned short nickname_len;
37 unsigned char *nickname;
38 unsigned short message_len;
39 unsigned char *message;
42 /* Parses private message payload returning new private mesage payload
43 structure. This also decrypts the message if the `cipher' is provided. */
45 SilcPrivateMessagePayload
46 silc_private_message_payload_parse(SilcBuffer buffer, SilcCipher cipher)
48 SilcPrivateMessagePayload new;
51 SILC_LOG_DEBUG(("Parsing private message payload"));
53 /* Decrypt the payload */
55 silc_cipher_decrypt(cipher, buffer->data, buffer->data,
56 buffer->len, cipher->iv);
58 new = silc_calloc(1, sizeof(*new));
60 /* Parse the Private Message Payload. Ignore the padding. */
61 ret = silc_buffer_unformat(buffer,
62 SILC_STR_UI_SHORT(&new->flags),
63 SILC_STR_UI16_NSTRING_ALLOC(&new->nickname,
65 SILC_STR_UI16_NSTRING_ALLOC(&new->message,
71 if ((new->message_len < 1 || new->message_len > buffer->len) ||
72 (new->nickname_len < 1 || new->nickname_len > buffer->len)) {
73 SILC_LOG_ERROR(("Incorrect private message payload in packet, "
81 silc_private_message_payload_free(new);
85 /* Encodes private message payload into a buffer and returns it. If
86 the cipher is provided the packet is also encrypted here. It is provided
87 if the private message private keys are used. */
89 SilcBuffer silc_private_message_payload_encode(unsigned short flags,
90 unsigned int nickname_len,
91 unsigned char *nickname,
92 unsigned short data_len,
98 unsigned int len, pad_len = 0;
99 unsigned char pad[SILC_PACKET_MAX_PADLEN];
101 SILC_LOG_DEBUG(("Encoding private message payload"));
103 len = 4 + nickname_len + 2 + data_len;
106 /* Calculate length of padding. */
107 pad_len = SILC_PACKET_PADLEN((len + 2));
110 /* Generate padding */
111 for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte();
114 /* Allocate private message payload buffer */
115 buffer = silc_buffer_alloc(len);
117 /* Encode the Channel Message Payload */
118 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
119 silc_buffer_format(buffer,
120 SILC_STR_UI_SHORT(flags),
121 SILC_STR_UI_SHORT(nickname_len),
122 SILC_STR_UI_XNSTRING(nickname, nickname_len),
123 SILC_STR_UI_SHORT(data_len),
124 SILC_STR_UI_XNSTRING(data, data_len),
125 SILC_STR_UI_XNSTRING(pad, pad_len),
129 /* Encrypt payload of the packet. */
130 silc_cipher_encrypt(cipher, buffer->data, buffer->data,
131 buffer->len, cipher->iv);
132 memset(pad, 0, sizeof(pad));
138 /* Free's Private Message Payload */
140 void silc_private_message_payload_free(SilcPrivateMessagePayload payload)
142 silc_free(payload->nickname);
143 if (payload->message) {
144 memset(payload->message, 0, payload->message_len);
145 silc_free(payload->message);
153 silc_private_message_get_flags(SilcPrivateMessagePayload payload)
155 return payload->flags;
158 /* Return nickname */
161 silc_private_message_get_nickname(SilcPrivateMessagePayload payload,
162 unsigned int *nickname_len)
165 *nickname_len = payload->nickname_len;
167 return payload->nickname;
173 silc_private_message_get_message(SilcPrivateMessagePayload payload,
174 unsigned int *message_len)
177 *message_len = payload->message_len;
179 return payload->message;