5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 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.
23 * Revision 1.1.1.1 2000/06/27 11:36:55 priikone
24 * Importet from internal CVS/Added Log headers.
29 #include "silcincludes.h"
30 #include "silcchannel.h"
32 /* Channel Payload structure. Contents of this structure is parsed
34 struct SilcChannelPayloadStruct {
35 unsigned short nick_len;
37 unsigned short data_len;
39 unsigned short iv_len;
43 /* Channel Key Payload structrue. Channel keys are parsed from SILC
44 packets into this structure. */
45 struct SilcChannelKeyPayloadStruct {
46 unsigned short id_len;
48 unsigned short cipher_len;
49 unsigned char *cipher;
50 unsigned short key_len;
54 /* Parses channel payload returning new channel payload structure */
56 SilcChannelPayload silc_channel_parse_payload(SilcBuffer buffer)
58 SilcChannelPayload new;
60 SILC_LOG_DEBUG(("Parsing channel payload"));
62 new = silc_calloc(1, sizeof(*new));
64 SILC_LOG_ERROR(("Could not allocate new channel payload"));
68 /* Parse the Channel Payload. Ignore padding and IV, we don't need
70 silc_buffer_unformat(buffer,
71 SILC_STR_UI16_NSTRING_ALLOC(&new->nick, &new->nick_len),
72 SILC_STR_UI16_NSTRING_ALLOC(&new->data, &new->data_len),
73 SILC_STR_UI16_NSTRING_ALLOC(NULL, NULL),
76 if (new->data_len < 1) {
77 SILC_LOG_ERROR(("Incorrect channel payload in packet, packet dropped"));
94 /* Encodes channel payload into a buffer and returns it. This is used
95 to add channel payload into a packet. As the channel payload is
96 encrypted separately from other parts of the packet padding must
97 be applied to the payload. */
99 SilcBuffer silc_channel_encode_payload(unsigned short nick_len,
101 unsigned short data_len,
103 unsigned short iv_len,
109 unsigned int len, pad_len;
110 unsigned char pad[SILC_PACKET_MAX_PADLEN];
112 SILC_LOG_DEBUG(("Encoding channel payload"));
114 /* Calculate length of padding. IV is not included into the calculation
115 since it is not encrypted. */
116 len = 2 + nick_len + 2 + data_len + 2;
117 pad_len = SILC_PACKET_PADLEN((len + 2));
119 /* Allocate channel payload buffer */
121 buffer = silc_buffer_alloc(len + iv_len);
125 /* Generate padding */
126 for (i = 0; i < pad_len; i++)
127 pad[i] = silc_rng_get_byte(rng);
129 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
131 /* Encode the Channel Payload */
132 silc_buffer_format(buffer,
133 SILC_STR_UI_SHORT(nick_len),
134 SILC_STR_UI_XNSTRING(nick, nick_len),
135 SILC_STR_UI_SHORT(data_len),
136 SILC_STR_UI_XNSTRING(data, data_len),
137 SILC_STR_UI_SHORT(pad_len),
138 SILC_STR_UI_XNSTRING(pad, pad_len),
139 SILC_STR_UI_XNSTRING(iv, iv_len),
142 memset(pad, 0, pad_len);
146 /* Free's Channel Payload */
148 void silc_channel_free_payload(SilcChannelPayload payload)
152 silc_free(payload->data);
154 silc_free(payload->iv);
159 /* Return nickname */
161 unsigned char *silc_channel_get_nickname(SilcChannelPayload payload,
162 unsigned int *nick_len)
165 *nick_len = payload->nick_len;
167 return payload->nick;
172 unsigned char *silc_channel_get_data(SilcChannelPayload payload,
173 unsigned int *data_len)
176 *data_len = payload->data_len;
178 return payload->data;
181 /* Return initial vector */
183 unsigned char *silc_channel_get_iv(SilcChannelPayload payload,
184 unsigned int *iv_len)
187 *iv_len = payload->iv_len;
192 /* Parses channel key payload returning new channel key payload structure */
194 SilcChannelKeyPayload silc_channel_key_parse_payload(SilcBuffer buffer)
196 SilcChannelKeyPayload new;
198 SILC_LOG_DEBUG(("Parsing channel key payload"));
200 new = silc_calloc(1, sizeof(*new));
202 SILC_LOG_ERROR(("Could not allocate new channel key payload"));
206 /* Parse the Channel Key Payload */
207 silc_buffer_unformat(buffer,
208 SILC_STR_UI16_NSTRING_ALLOC(&new->id, &new->id_len),
209 SILC_STR_UI16_NSTRING_ALLOC(&new->cipher,
211 SILC_STR_UI16_NSTRING_ALLOC(&new->key, &new->key_len),
214 if (new->id_len < 1 || new->key_len < 1 || new->cipher_len < 1) {
215 SILC_LOG_ERROR(("Incorrect channel key payload in packet"));
225 silc_free(new->cipher);
232 /* Encodes channel key payload into a buffer and returns it. This is used
233 to add channel key payload into a packet. */
235 SilcBuffer silc_channel_key_encode_payload(unsigned short id_len,
237 unsigned short cipher_len,
238 unsigned char *cipher,
239 unsigned short key_len,
245 SILC_LOG_DEBUG(("Encoding channel key payload"));
248 if (!id_len || !key_len || !id || !key || !cipher_len || !cipher)
251 /* Allocate channel payload buffer. Length is 2 + id + 2 + key +
253 len = 2 + id_len + 2 + key_len + 2 + cipher_len;
254 buffer = silc_buffer_alloc(len);
258 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
260 /* Encode the Channel Payload */
261 silc_buffer_format(buffer,
262 SILC_STR_UI_SHORT(id_len),
263 SILC_STR_UI_XNSTRING(id, id_len),
264 SILC_STR_UI_SHORT(cipher_len),
265 SILC_STR_UI_XNSTRING(cipher, cipher_len),
266 SILC_STR_UI_SHORT(key_len),
267 SILC_STR_UI_XNSTRING(key, key_len),
273 /* Free's Channel Key Payload */
275 void silc_channel_key_free_payload(SilcChannelKeyPayload payload)
279 silc_free(payload->id);
281 silc_free(payload->cipher);
283 memset(payload->key, 0, payload->key_len);
284 silc_free(payload->key);
292 unsigned char *silc_channel_key_get_id(SilcChannelKeyPayload payload,
293 unsigned int *id_len)
296 *id_len = payload->id_len;
301 /* Return cipher name */
303 unsigned char *silc_channel_key_get_cipher(SilcChannelKeyPayload payload,
304 unsigned int *cipher_len)
307 *cipher_len = payload->cipher_len;
309 return payload->cipher;
314 unsigned char *silc_channel_key_get_key(SilcChannelKeyPayload payload,
315 unsigned int *key_len)
318 *key_len = payload->key_len;