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 if (len1 - 2 > buffer->len) {
467 SILC_LOG_DEBUG(("Garbage in header of packet, bad packet length, "
472 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
473 buffer->data + 2, len1 - 2,
475 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
481 /* Decrypts a packet. This assumes that typical SILC packet is the
482 packet to be decrypted and thus checks for normal and special SILC
483 packets and can handle both of them. This also computes and checks
484 the HMAC of the packet. If any other special or customized decryption
485 processing is required this function cannot be used. This returns
486 -1 on error, 0 when packet is normal packet and 1 when the packet
487 is special and requires special processing.
489 The `check_packet' is a callback funtion that this function will
490 call. The callback relates to the checking whether the packet is
491 normal packet or special packet and how it should be processed. If
492 the callback return TRUE the packet is normal and FALSE if the packet
493 is special and requires special procesing. */
495 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
496 SilcBuffer buffer, SilcPacketContext *packet,
497 SilcPacketCheckDecrypt check_packet,
502 /* Decrypt start of the packet header */
504 silc_cipher_decrypt(cipher, buffer->data + 2, buffer->data + 2,
505 SILC_PACKET_MIN_HEADER_LEN - 2, cipher->iv);
507 /* Do packet checking, whether the packet is normal or special */
508 check = check_packet((SilcPacketType)buffer->data[3], buffer,
511 /* If the packet type is not any special type lets decrypt rest
512 of the packet here. */
514 /* Normal packet, decrypt rest of the packet */
515 if (!silc_packet_decrypt_rest(cipher, hmac, buffer))
519 if (!silc_packet_check_mac(hmac, buffer))
524 /* Packet requires special handling, decrypt rest of the header.
525 This only decrypts. */
526 if (!silc_packet_decrypt_rest_special(cipher, hmac, buffer))
530 if (!silc_packet_check_mac(hmac, buffer))
537 /* Parses the packet. This is called when a whole packet is ready to be
538 parsed. The buffer sent must be already decrypted before calling this
539 function. The len argument must be the true length of the packet. This
540 function returns the type of the packet. The data section of the
541 buffer is parsed, not head or tail sections. */
543 SilcPacketType silc_packet_parse(SilcPacketContext *ctx)
545 SilcBuffer buffer = ctx->buffer;
548 SILC_LOG_DEBUG(("Parsing incoming packet"));
550 /* Check the length of the buffer */
551 if (buffer->len < SILC_PACKET_MIN_LEN) {
552 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
553 return SILC_PACKET_NONE;
556 /* Parse the buffer. This parses the SILC header of the packet. */
557 len = silc_buffer_unformat(buffer,
558 SILC_STR_UI_SHORT(&ctx->truelen),
559 SILC_STR_UI_CHAR(&ctx->flags),
560 SILC_STR_UI_CHAR(&ctx->type),
561 SILC_STR_UI_SHORT(&ctx->src_id_len),
562 SILC_STR_UI_SHORT(&ctx->dst_id_len),
563 SILC_STR_UI_CHAR(&ctx->src_id_type),
566 return SILC_PACKET_NONE;
568 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
569 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
570 SILC_LOG_ERROR(("Bad ID lengths in packet"));
571 return SILC_PACKET_NONE;
574 /* Calculate length of padding in packet */
575 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
577 silc_buffer_pull(buffer, len);
578 ret = silc_buffer_unformat(buffer,
579 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
581 SILC_STR_UI_CHAR(&ctx->dst_id_type),
582 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
584 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
587 return SILC_PACKET_NONE;
589 silc_buffer_push(buffer, len);
591 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
592 ctx->buffer->data, ctx->buffer->len);
594 /* Pull SILC header and padding from packet */
595 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
596 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
598 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
603 /* Perform special SILC Packet header parsing. This is required to some
604 packet types that have the data payload encrypted with different key
605 than the header area plus padding of the packet. Hence, this parses
606 the header in a way that it does not take the data area into account
607 and parses the header and padding area only. */
609 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
611 SilcBuffer buffer = ctx->buffer;
612 int len, tmplen, ret;
614 SILC_LOG_DEBUG(("Parsing incoming packet"));
616 /* Check the length of the buffer */
617 if (buffer->len < SILC_PACKET_MIN_LEN) {
618 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
619 return SILC_PACKET_NONE;
622 /* Parse the buffer. This parses the SILC header of the packet. */
623 len = silc_buffer_unformat(buffer,
624 SILC_STR_UI_SHORT(&ctx->truelen),
625 SILC_STR_UI_CHAR(&ctx->flags),
626 SILC_STR_UI_CHAR(&ctx->type),
627 SILC_STR_UI_SHORT(&ctx->src_id_len),
628 SILC_STR_UI_SHORT(&ctx->dst_id_len),
629 SILC_STR_UI_CHAR(&ctx->src_id_type),
632 return SILC_PACKET_NONE;
634 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
635 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
636 SILC_LOG_ERROR(("Bad ID lengths in packet"));
637 return SILC_PACKET_NONE;
640 /* Calculate length of padding in packet. As this is special packet
641 the data area is not used in the padding calculation as it won't
642 be decrypted by the caller. */
643 tmplen = SILC_PACKET_HEADER_LEN + ctx->src_id_len + ctx->dst_id_len;
644 ctx->padlen = SILC_PACKET_PADLEN(tmplen);
646 silc_buffer_pull(buffer, len);
647 ret = silc_buffer_unformat(buffer,
648 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
650 SILC_STR_UI_CHAR(&ctx->dst_id_type),
651 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
653 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
656 return SILC_PACKET_NONE;
658 silc_buffer_push(buffer, len);
660 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
661 ctx->buffer->data, ctx->buffer->len);
663 /* Pull SILC header and padding from packet */
664 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
665 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
667 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
672 /* Allocate packet context */
674 SilcPacketContext *silc_packet_context_alloc(void)
676 SilcPacketContext *ctx = silc_calloc(1, sizeof(*ctx));
681 /* Increse the reference count of the packet context. */
683 SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx)
686 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users - 1,
691 /* Decrese the reference count of the packet context and free it only if
694 void silc_packet_context_free(SilcPacketContext *ctx)
697 SILC_LOG_DEBUG(("Packet context %p refcnt %d->%d", ctx, ctx->users + 1,
702 silc_buffer_free(ctx->buffer);
704 silc_free(ctx->src_id);
706 silc_free(ctx->dst_id);