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.
20 /* Channel Payload and Channel Key Payload implementations. */
23 #include "silcincludes.h"
24 #include "silcchannel.h"
26 /******************************************************************************
30 ******************************************************************************/
32 /* Channel Payload structure. Contents of this structure is parsed
34 struct SilcChannelPayloadStruct {
35 unsigned short data_len;
37 unsigned short iv_len;
41 /* Parses channel payload returning new channel payload structure */
43 SilcChannelPayload silc_channel_payload_parse(SilcBuffer buffer)
45 SilcChannelPayload new;
48 SILC_LOG_DEBUG(("Parsing channel payload"));
50 new = silc_calloc(1, sizeof(*new));
52 /* Parse the Channel Payload. Ignore padding and IV, we don't need
54 ret = silc_buffer_unformat(buffer,
55 SILC_STR_UI16_NSTRING_ALLOC(&new->data,
57 SILC_STR_UI16_NSTRING_ALLOC(NULL, NULL),
62 if (new->data_len < 1 || new->data_len > buffer->len) {
63 SILC_LOG_ERROR(("Incorrect channel payload in packet, packet dropped"));
78 /* Encodes channel payload into a buffer and returns it. This is used
79 to add channel payload into a packet. As the channel payload is
80 encrypted separately from other parts of the packet padding must
81 be applied to the payload. */
83 SilcBuffer silc_channel_payload_encode(unsigned short data_len,
85 unsigned short iv_len,
91 unsigned int len, pad_len;
92 unsigned char pad[SILC_PACKET_MAX_PADLEN];
94 SILC_LOG_DEBUG(("Encoding channel payload"));
96 /* Calculate length of padding. IV is not included into the calculation
97 since it is not encrypted. */
98 len = 2 + data_len + 2;
99 pad_len = SILC_PACKET_PADLEN((len + 2));
101 /* Allocate channel payload buffer */
103 buffer = silc_buffer_alloc(len + iv_len);
104 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
106 /* Generate padding */
107 for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte(rng);
109 /* Encode the Channel Payload */
110 silc_buffer_format(buffer,
111 SILC_STR_UI_SHORT(data_len),
112 SILC_STR_UI_XNSTRING(data, data_len),
113 SILC_STR_UI_SHORT(pad_len),
114 SILC_STR_UI_XNSTRING(pad, pad_len),
115 SILC_STR_UI_XNSTRING(iv, iv_len),
118 memset(pad, 0, pad_len);
122 /* Free's Channel Payload */
124 void silc_channel_payload_free(SilcChannelPayload payload)
128 silc_free(payload->data);
130 silc_free(payload->iv);
137 unsigned char *silc_channel_get_data(SilcChannelPayload payload,
138 unsigned int *data_len)
141 *data_len = payload->data_len;
143 return payload->data;
146 /* Return initial vector */
148 unsigned char *silc_channel_get_iv(SilcChannelPayload payload,
149 unsigned int *iv_len)
152 *iv_len = payload->iv_len;
157 /******************************************************************************
161 ******************************************************************************/
163 /* Channel Key Payload structrue. Channel keys are parsed from SILC
164 packets into this structure. */
165 struct SilcChannelKeyPayloadStruct {
166 unsigned short id_len;
168 unsigned short cipher_len;
169 unsigned char *cipher;
170 unsigned short key_len;
174 /* Parses channel key payload returning new channel key payload structure */
176 SilcChannelKeyPayload silc_channel_key_payload_parse(SilcBuffer buffer)
178 SilcChannelKeyPayload new;
181 SILC_LOG_DEBUG(("Parsing channel key payload"));
183 new = silc_calloc(1, sizeof(*new));
185 /* Parse the Channel Key Payload */
187 silc_buffer_unformat(buffer,
188 SILC_STR_UI16_NSTRING_ALLOC(&new->id, &new->id_len),
189 SILC_STR_UI16_NSTRING_ALLOC(&new->cipher,
191 SILC_STR_UI16_NSTRING_ALLOC(&new->key, &new->key_len),
196 if (new->id_len < 1 || new->key_len < 1 || new->cipher_len < 1) {
197 SILC_LOG_ERROR(("Incorrect channel key payload in packet"));
207 silc_free(new->cipher);
214 /* Encodes channel key payload into a buffer and returns it. This is used
215 to add channel key payload into a packet. */
217 SilcBuffer silc_channel_key_payload_encode(unsigned short id_len,
219 unsigned short cipher_len,
220 unsigned char *cipher,
221 unsigned short key_len,
227 SILC_LOG_DEBUG(("Encoding channel key payload"));
229 /* Allocate channel payload buffer. Length is 2 + id + 2 + key +
231 len = 2 + id_len + 2 + key_len + 2 + cipher_len;
232 buffer = silc_buffer_alloc(len);
234 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
236 /* Encode the Channel Payload */
237 silc_buffer_format(buffer,
238 SILC_STR_UI_SHORT(id_len),
239 SILC_STR_UI_XNSTRING(id, id_len),
240 SILC_STR_UI_SHORT(cipher_len),
241 SILC_STR_UI_XNSTRING(cipher, cipher_len),
242 SILC_STR_UI_SHORT(key_len),
243 SILC_STR_UI_XNSTRING(key, key_len),
249 /* Free's Channel Key Payload */
251 void silc_channel_key_payload_free(SilcChannelKeyPayload payload)
255 silc_free(payload->id);
257 silc_free(payload->cipher);
259 memset(payload->key, 0, payload->key_len);
260 silc_free(payload->key);
268 unsigned char *silc_channel_key_get_id(SilcChannelKeyPayload payload,
269 unsigned int *id_len)
272 *id_len = payload->id_len;
277 /* Return cipher name */
279 unsigned char *silc_channel_key_get_cipher(SilcChannelKeyPayload payload,
280 unsigned int *cipher_len)
283 *cipher_len = payload->cipher_len;
285 return payload->cipher;
290 unsigned char *silc_channel_key_get_key(SilcChannelKeyPayload payload,
291 unsigned int *key_len)
294 *key_len = payload->key_len;