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.
21 * Created: Fri Jul 25 18:52:14 1997
25 #include "silcincludes.h"
27 /******************************************************************************
29 Packet Sending Routines
31 ******************************************************************************/
33 /* Actually sends the packet. This flushes the connections outgoing data
34 buffer. If data is sent directly to the network this returns the bytes
35 written, if error occured this returns -1 and if the data could not
36 be written directly to the network at this time this returns -2, in
37 which case the data should be queued by the caller and sent at some
38 later time. If `force_send' is TRUE this attempts to write the data
39 directly to the network, if FALSE, this returns -2. */
41 int silc_packet_send(SilcSocketConnection sock, int force_send)
43 SILC_LOG_DEBUG(("Sending packet to %s:%d [%s]", sock->hostname,
45 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
46 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
47 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
50 /* Send now if forced to do so */
51 if (force_send == TRUE) {
54 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
56 /* Write to network */
57 ret = silc_socket_write(sock);
60 SILC_LOG_ERROR(("Error sending packet, dropped"));
65 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
68 SILC_LOG_DEBUG(("Packet in queue"));
73 /* Encrypts a packet. This also creates HMAC of the packet before
74 encryption and adds the HMAC at the end of the buffer. This assumes
75 that there is enough free space at the end of the buffer to add the
76 computed HMAC. This is the normal way of encrypting packets, if some
77 other process of HMAC computing and encryption is needed this function
80 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac,
81 SilcBuffer buffer, uint32 len)
83 unsigned char mac[32];
86 /* Compute HMAC. This assumes that HMAC is created from the entire
87 data area thus this uses the length found in buffer, not the length
90 silc_hmac_make(hmac, buffer->data, buffer->len, mac, &mac_len);
91 silc_buffer_put_tail(buffer, mac, mac_len);
92 memset(mac, 0, sizeof(mac));
95 /* Encrypt the data area of the packet. 2 bytes of the packet
98 SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d (%d)",
99 cipher->cipher->name, len, len - 2));
100 cipher->cipher->encrypt(cipher->context, buffer->data + 2,
101 buffer->data + 2, len - 2, cipher->iv);
104 /* Pull the HMAC into the visible data area in the buffer */
106 silc_buffer_pull_tail(buffer, mac_len);
109 /* Assembles a new packet to be ready for send out. The buffer sent as
110 argument must include the data to be sent and it must not be encrypted.
111 The packet also must have enough free space so that the SILC header
112 and padding maybe added to the packet. The packet is encrypted after
113 this function has returned.
115 The buffer sent as argument should be something like following:
117 --------------------------------------------
118 | head | data | tail |
119 --------------------------------------------
123 So that the SILC header and 1 - 16 bytes of padding can fit to
124 the buffer. After assembly the buffer might look like this:
126 --------------------------------------------
128 --------------------------------------------
130 Start of assembled packet
132 Packet construct is as follows (* = won't be encrypted):
135 2 bytes Payload length (*)
138 2 bytes Source ID Length
139 2 bytes Destination ID Length
140 1 byte Source ID Type
142 1 byte Destination ID Type
143 n bytes Destination ID
149 All fields in the packet will be authenticated by MAC. The MAC is
150 not computed here, it must be computed separately before encrypting
155 void silc_packet_assemble(SilcPacketContext *ctx)
157 unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
160 SILC_LOG_DEBUG(("Assembling outgoing packet"));
162 /* Get the true length of the packet. This is saved as payload length
163 into the packet header. This does not include the length of the
166 ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN +
167 ctx->src_id_len + ctx->dst_id_len;
169 /* Calculate the length of the padding. The padding is calculated from
170 the data that will be encrypted. As protocol states 3 first bytes
171 of the packet are not encrypted they are not included in the
172 padding calculation. */
174 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
176 /* Put the start of the data section to the right place. */
177 silc_buffer_push(ctx->buffer, SILC_PACKET_HEADER_LEN +
178 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
180 /* Get random padding */
182 for (i = 0; i < ctx->padlen; i++) tmppad[i] = silc_rng_global_get_byte();
184 /* XXX: For testing - to be removed */
185 memset(tmppad, 65, sizeof(tmppad));
188 /* Create the packet. This creates the SILC header and adds padding,
189 rest of the buffer remains as it is. */
190 silc_buffer_format(ctx->buffer,
191 SILC_STR_UI_SHORT(ctx->truelen),
192 SILC_STR_UI_CHAR(ctx->flags),
193 SILC_STR_UI_CHAR(ctx->type),
194 SILC_STR_UI_SHORT(ctx->src_id_len),
195 SILC_STR_UI_SHORT(ctx->dst_id_len),
196 SILC_STR_UI_CHAR(ctx->src_id_type),
197 SILC_STR_UI_XNSTRING(ctx->src_id, ctx->src_id_len),
198 SILC_STR_UI_CHAR(ctx->dst_id_type),
199 SILC_STR_UI_XNSTRING(ctx->dst_id, ctx->dst_id_len),
200 SILC_STR_UI_XNSTRING(tmppad, ctx->padlen),
203 SILC_LOG_HEXDUMP(("Assembled packet, len %d", ctx->buffer->len),
204 ctx->buffer->data, ctx->buffer->len);
206 SILC_LOG_DEBUG(("Outgoing packet assembled"));
209 /* Prepare outgoing data buffer for packet sending. This moves the data
210 area so that new packet may be added into it. If needed this allocates
211 more space to the buffer. This handles directly the connection's
212 outgoing buffer in SilcSocketConnection object. */
214 void silc_packet_send_prepare(SilcSocketConnection sock,
221 totlen = header_len + padlen + data_len;
223 /* Prepare the outgoing buffer for packet sending. */
225 /* Allocate new buffer. This is done only once per connection. */
226 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
228 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
229 silc_buffer_pull_tail(sock->outbuf, totlen);
230 silc_buffer_pull(sock->outbuf, header_len + padlen);
232 if (SILC_IS_OUTBUF_PENDING(sock)) {
233 /* There is some pending data in the buffer. */
235 /* Allocate more space if needed */
236 if ((sock->outbuf->end - sock->outbuf->tail) <
238 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
239 sock->outbuf = silc_buffer_realloc(sock->outbuf,
240 sock->outbuf->truelen +
244 oldlen = sock->outbuf->len;
245 silc_buffer_pull_tail(sock->outbuf, totlen);
246 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
248 /* Buffer is free for use */
249 silc_buffer_clear(sock->outbuf);
251 /* Allocate more space if needed */
252 if ((sock->outbuf->end - sock->outbuf->tail) < (totlen + 20)) {
253 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
254 sock->outbuf = silc_buffer_realloc(sock->outbuf,
255 sock->outbuf->truelen +
259 silc_buffer_pull_tail(sock->outbuf, totlen);
260 silc_buffer_pull(sock->outbuf, header_len + padlen);
265 /******************************************************************************
267 Packet Reception Routines
269 ******************************************************************************/
271 /* Processes the received data. This checks the received data and
272 calls parser callback that handles the actual packet decryption
273 and parsing. If more than one packet was received this calls the
274 parser multiple times. The parser callback will get context
275 SilcPacketParserContext that includes the packet and the `context'
276 sent to this function. */
278 void silc_packet_receive_process(SilcSocketConnection sock,
279 SilcCipher cipher, SilcHmac hmac,
280 SilcPacketParserCallback parser,
283 SilcPacketParserContext *parse_ctx;
284 int packetlen, paddedlen, count, mac_len = 0;
286 /* We need at least 2 bytes of data to be able to start processing
288 if (sock->inbuf->len < 2)
292 mac_len = hmac->hmac->len;
294 /* Parse the packets from the data */
296 while (sock->inbuf->len > 0) {
297 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
301 if (packetlen < SILC_PACKET_MIN_LEN) {
302 SILC_LOG_DEBUG(("Received invalid packet, dropped"));
303 silc_buffer_clear(sock->inbuf);
307 if (sock->inbuf->len < paddedlen + mac_len) {
308 SILC_LOG_DEBUG(("Received partial packet, waiting for the rest"));
312 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
313 parse_ctx->packet = silc_packet_context_alloc();
314 parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
315 parse_ctx->sock = sock;
316 parse_ctx->context = context;
318 silc_buffer_pull_tail(parse_ctx->packet->buffer,
319 SILC_BUFFER_END(parse_ctx->packet->buffer));
320 silc_buffer_put(parse_ctx->packet->buffer, sock->inbuf->data,
321 paddedlen + mac_len);
323 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
324 parse_ctx->packet->buffer->len),
325 parse_ctx->packet->buffer->data,
326 parse_ctx->packet->buffer->len);
328 /* Call the parser */
330 (*parser)(parse_ctx);
332 /* Pull the packet from inbuf thus we'll get the next one
334 silc_buffer_pull(sock->inbuf, paddedlen);
336 silc_buffer_pull(sock->inbuf, mac_len);
339 SILC_LOG_DEBUG(("Clearing inbound buffer"));
340 silc_buffer_clear(sock->inbuf);
343 /* Receives packet from network and reads the data into connection's
344 incoming data buffer. If the data was read directly this returns the
345 read bytes, if error occured this returns -1, if the data could not
346 be read directly at this time this returns -2 in which case the data
347 should be read again at some later time, or If EOF occured this returns
350 int silc_packet_receive(SilcSocketConnection sock)
354 SILC_LOG_DEBUG(("Receiving packet from %s:%d [%s]", sock->hostname,
356 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
357 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
358 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
361 /* Read some data from connection */
362 ret = silc_socket_read(sock);
367 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
368 after packet has been totally decrypted and parsed. */
370 static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer)
374 unsigned char mac[32];
377 SILC_LOG_DEBUG(("Verifying MAC"));
379 /* Compute HMAC of packet */
380 memset(mac, 0, sizeof(mac));
381 silc_hmac_make(hmac, buffer->data, buffer->len, mac, &mac_len);
383 /* Compare the HMAC's (buffer->tail has the packet's HMAC) */
384 if (memcmp(mac, buffer->tail, mac_len)) {
385 SILC_LOG_ERROR(("MAC failed"));
389 SILC_LOG_DEBUG(("MAC is Ok"));
390 memset(mac, 0, sizeof(mac));
396 /* Decrypts rest of the packet (after decrypting just the SILC header).
397 After calling this function the packet is ready to be parsed by calling
398 silc_packet_parse. If everything goes without errors this returns TRUE,
399 if packet is malformed this returns FALSE. */
401 static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac,
406 /* Pull MAC from packet before decryption */
408 if ((buffer->len - hmac->hmac->len) > SILC_PACKET_MIN_LEN) {
409 silc_buffer_push_tail(buffer, hmac->hmac->len);
411 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
416 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
418 /* Decrypt rest of the packet */
419 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
420 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
421 buffer->data + 2, buffer->len - 2,
423 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
425 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
426 buffer->data, buffer->len);
432 /* Decrypts rest of the SILC Packet header that has been decrypted partly
433 already. This decrypts the padding of the packet also. After calling
434 this function the packet is ready to be parsed by calling function
435 silc_packet_parse. This is used in special packet reception (protocol
436 defines the way of decrypting special packets). */
438 static int silc_packet_decrypt_rest_special(SilcCipher cipher,
442 /* Decrypt rest of the header plus padding */
444 uint16 truelen, len1, len2, padlen;
446 /* Pull MAC from packet before decryption */
448 if ((buffer->len - hmac->hmac->len) > SILC_PACKET_MIN_LEN) {
449 silc_buffer_push_tail(buffer, hmac->hmac->len);
451 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
456 SILC_LOG_DEBUG(("Decrypting rest of the header"));
458 SILC_GET16_MSB(len1, &buffer->data[4]);
459 SILC_GET16_MSB(len2, &buffer->data[6]);
461 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
462 padlen = SILC_PACKET_PADLEN(truelen);
463 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
465 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
466 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
467 buffer->data + 2, len1 - 2,
469 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
475 /* Decrypts a packet. This assumes that typical SILC packet is the
476 packet to be decrypted and thus checks for normal and special SILC
477 packets and can handle both of them. This also computes and checks
478 the HMAC of the packet. If any other special or customized decryption
479 processing is required this function cannot be used. This returns
480 -1 on error, 0 when packet is normal packet and 1 when the packet
481 is special and requires special processing.
483 The `check_packet' is a callback funtion that this function will
484 call. The callback relates to the checking whether the packet is
485 normal packet or special packet and how it should be processed. If
486 the callback return TRUE the packet is normal and FALSE if the packet
487 is special and requires special procesing. */
489 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
490 SilcBuffer buffer, SilcPacketContext *packet,
491 SilcPacketCheckDecrypt check_packet,
496 /* Decrypt start of the packet header */
498 silc_cipher_decrypt(cipher, buffer->data + 2, buffer->data + 2,
499 SILC_PACKET_MIN_HEADER_LEN - 2, cipher->iv);
501 /* Do packet checking, whether the packet is normal or special */
502 check = check_packet((SilcPacketType)buffer->data[3], buffer,
505 /* If the packet type is not any special type lets decrypt rest
506 of the packet here. */
508 /* Normal packet, decrypt rest of the packet */
509 if (!silc_packet_decrypt_rest(cipher, hmac, buffer))
513 if (!silc_packet_check_mac(hmac, buffer))
518 /* Packet requires special handling, decrypt rest of the header.
519 This only decrypts. */
520 if (!silc_packet_decrypt_rest_special(cipher, hmac, buffer))
524 if (!silc_packet_check_mac(hmac, buffer))
531 /* Parses the packet. This is called when a whole packet is ready to be
532 parsed. The buffer sent must be already decrypted before calling this
533 function. The len argument must be the true length of the packet. This
534 function returns the type of the packet. The data section of the
535 buffer is parsed, not head or tail sections. */
537 SilcPacketType silc_packet_parse(SilcPacketContext *ctx)
539 SilcBuffer buffer = ctx->buffer;
542 SILC_LOG_DEBUG(("Parsing incoming packet"));
544 /* Check the length of the buffer */
545 if (buffer->len < SILC_PACKET_MIN_LEN) {
546 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
547 return SILC_PACKET_NONE;
550 /* Parse the buffer. This parses the SILC header of the packet. */
551 len = silc_buffer_unformat(buffer,
552 SILC_STR_UI_SHORT(&ctx->truelen),
553 SILC_STR_UI_CHAR(&ctx->flags),
554 SILC_STR_UI_CHAR(&ctx->type),
555 SILC_STR_UI_SHORT(&ctx->src_id_len),
556 SILC_STR_UI_SHORT(&ctx->dst_id_len),
557 SILC_STR_UI_CHAR(&ctx->src_id_type),
560 return SILC_PACKET_NONE;
562 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
563 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
564 SILC_LOG_ERROR(("Bad ID lengths in packet"));
565 return SILC_PACKET_NONE;
568 /* Calculate length of padding in packet */
569 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
571 silc_buffer_pull(buffer, len);
572 ret = silc_buffer_unformat(buffer,
573 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
575 SILC_STR_UI_CHAR(&ctx->dst_id_type),
576 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
578 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
581 return SILC_PACKET_NONE;
583 silc_buffer_push(buffer, len);
585 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
586 ctx->buffer->data, ctx->buffer->len);
588 /* Pull SILC header and padding from packet */
589 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
590 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
592 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
597 /* Perform special SILC Packet header parsing. This is required to some
598 packet types that have the data payload encrypted with different key
599 than the header area plus padding of the packet. Hence, this parses
600 the header in a way that it does not take the data area into account
601 and parses the header and padding area only. */
603 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
605 SilcBuffer buffer = ctx->buffer;
606 int len, tmplen, ret;
608 SILC_LOG_DEBUG(("Parsing incoming packet"));
610 /* Check the length of the buffer */
611 if (buffer->len < SILC_PACKET_MIN_LEN) {
612 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
613 return SILC_PACKET_NONE;
616 /* Parse the buffer. This parses the SILC header of the packet. */
617 len = silc_buffer_unformat(buffer,
618 SILC_STR_UI_SHORT(&ctx->truelen),
619 SILC_STR_UI_CHAR(&ctx->flags),
620 SILC_STR_UI_CHAR(&ctx->type),
621 SILC_STR_UI_SHORT(&ctx->src_id_len),
622 SILC_STR_UI_SHORT(&ctx->dst_id_len),
623 SILC_STR_UI_CHAR(&ctx->src_id_type),
626 return SILC_PACKET_NONE;
628 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
629 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
630 SILC_LOG_ERROR(("Bad ID lengths in packet"));
631 return SILC_PACKET_NONE;
634 /* Calculate length of padding in packet. As this is special packet
635 the data area is not used in the padding calculation as it won't
636 be decrypted by the caller. */
637 tmplen = SILC_PACKET_HEADER_LEN + ctx->src_id_len + ctx->dst_id_len;
638 ctx->padlen = SILC_PACKET_PADLEN(tmplen);
640 silc_buffer_pull(buffer, len);
641 ret = silc_buffer_unformat(buffer,
642 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
644 SILC_STR_UI_CHAR(&ctx->dst_id_type),
645 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
647 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
650 return SILC_PACKET_NONE;
652 silc_buffer_push(buffer, len);
654 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
655 ctx->buffer->data, ctx->buffer->len);
657 /* Pull SILC header and padding from packet */
658 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
659 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
661 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
666 /* Allocate packet context */
668 SilcPacketContext *silc_packet_context_alloc()
670 SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx));
675 /* Increse the reference count of the packet context. */
677 SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx)
680 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users - 1,
685 /* Decrese the reference count of the packet context and free it only if
688 void silc_packet_context_free(SilcPacketContext *ctx)
691 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users + 1,
696 silc_buffer_free(ctx->buffer);
698 silc_free(ctx->src_id);
700 silc_free(ctx->dst_id);