Exemple #1
0
SilcBuffer silc_public_key_payload_encode(SilcPublicKey public_key)
{
  SilcBuffer buffer;
  unsigned char *pk;
  SilcUInt32 pk_len;
  SilcPKCSType type;

  if (!public_key)
    return NULL;

  type = silc_pkcs_get_type(public_key);
  pk = silc_pkcs_public_key_encode(public_key, &pk_len);
  if (!pk)
    return NULL;

  buffer = silc_buffer_alloc_size(4 + pk_len);
  if (!buffer) {
    silc_free(pk);
    return NULL;
  }

  if (silc_buffer_format(buffer,
			 SILC_STR_UI_SHORT(pk_len),
			 SILC_STR_UI_SHORT(type),
			 SILC_STR_DATA(pk, pk_len),
			 SILC_STR_END) < 0) {
    silc_buffer_free(buffer);
    silc_free(pk);
    return NULL;
  }

  silc_free(pk);
  return buffer;
}
Exemple #2
0
SilcBool silc_public_key_payload_decode(unsigned char *data,
					SilcUInt32 data_len,
					SilcPublicKey *public_key)
{
  SilcBufferStruct buf;
  SilcUInt16 pk_len, pk_type;
  unsigned char *pk;
  int ret;

  if (!public_key)
    return FALSE;

  silc_buffer_set(&buf, data, data_len);
  ret = silc_buffer_unformat(&buf,
			     SILC_STR_ADVANCE,
			     SILC_STR_UI_SHORT(&pk_len),
			     SILC_STR_UI_SHORT(&pk_type),
			     SILC_STR_END);
  if (ret < 0 || pk_len > data_len - 4)
    return FALSE;

  if (pk_type < SILC_PKCS_SILC || pk_type > SILC_PKCS_SPKI)
    return FALSE;

  ret = silc_buffer_unformat(&buf,
			     SILC_STR_DATA(&pk, pk_len),
			     SILC_STR_END);
  if (ret < 0)
    return FALSE;

  return silc_pkcs_public_key_alloc((SilcPKCSType)pk_type,
				    pk, pk_len, public_key);
}
Exemple #3
0
SilcBuffer silc_notify_payload_encode_args(SilcNotifyType type,
					   SilcUInt32 argc,
					   SilcBuffer args)
{
  SilcBuffer buffer;
  SilcUInt32 len;

  len = 5 + (args ? silc_buffer_len(args) : 0);
  buffer = silc_buffer_alloc_size(len);
  if (!buffer)
    return NULL;
  silc_buffer_format(buffer,
		     SILC_STR_UI_SHORT(type),
		     SILC_STR_UI_SHORT(len),
		     SILC_STR_UI_CHAR(argc),
		     SILC_STR_END);

  if (args)
    silc_buffer_format(buffer,
		       SILC_STR_OFFSET(5),
		       SILC_STR_DATA(args->data, silc_buffer_len(args)),
		       SILC_STR_END);

  return buffer;
}
Exemple #4
0
void silcpurple_wb_send(PurpleWhiteboard *wb, GList *draw_list)
{
	SilcPurpleWb wbs = wb->proto_data;
	SilcBuffer packet;
	GList *list;
	int len;
        PurpleConnection *gc;
        SilcPurple sg;

	g_return_if_fail(draw_list);
	gc = purple_account_get_connection(wb->account);
	g_return_if_fail(gc);
 	sg = gc->proto_data;
	g_return_if_fail(sg);

	len = SILCPURPLE_WB_HEADER;
	for (list = draw_list; list; list = list->next)
		len += 4;

	packet = silc_buffer_alloc_size(len);
	if (!packet)
		return;

	/* Assmeble packet */
	silc_buffer_format(packet,
			   SILC_STR_UI32_STRING(SILCPURPLE_WB_MIME),
			   SILC_STR_UI_CHAR(SILCPURPLE_WB_DRAW),
			   SILC_STR_UI_SHORT(wbs->width),
			   SILC_STR_UI_SHORT(wbs->height),
			   SILC_STR_UI_INT(wbs->brush_color),
			   SILC_STR_UI_SHORT(wbs->brush_size),
			   SILC_STR_END);
	silc_buffer_pull(packet, SILCPURPLE_WB_HEADER);
	for (list = draw_list; list; list = list->next) {
		silc_buffer_format(packet,
				   SILC_STR_UI_INT(GPOINTER_TO_INT(list->data)),
				   SILC_STR_END);
		silc_buffer_pull(packet, 4);
	}

	/* Send the message */
	if (wbs->type == 0) {
		/* Private message */
		silc_client_send_private_message(sg->client, sg->conn,
						 wbs->u.client,
						 SILC_MESSAGE_FLAG_DATA, NULL,
						 packet->head, len);
	} else if (wbs->type == 1) {
		/* Channel message. Channel private keys are not supported. */
		silc_client_send_channel_message(sg->client, sg->conn,
						 wbs->u.channel, NULL,
						 SILC_MESSAGE_FLAG_DATA, NULL,
						 packet->head, len);
	}

	silc_buffer_free(packet);
}
Exemple #5
0
static void
silcpurple_wb_parse(SilcPurpleWb wbs, PurpleWhiteboard *wb,
		  unsigned char *message, SilcUInt32 message_len)
{
	SilcUInt8 command;
	SilcUInt16 width, height, brush_size;
	SilcUInt32 brush_color, x, y, dx, dy;
	SilcBufferStruct buf;
	int ret;

	/* Parse the packet */
	silc_buffer_set(&buf, message, message_len);
	ret = silc_buffer_unformat(&buf,
				   SILC_STR_UI_CHAR(&command),
				   SILC_STR_UI_SHORT(&width),
				   SILC_STR_UI_SHORT(&height),
				   SILC_STR_UI_INT(&brush_color),
				   SILC_STR_UI_SHORT(&brush_size),
				   SILC_STR_END);
	if (ret < 0)
		return;
	silc_buffer_pull(&buf, ret);

	/* Update whiteboard if its dimensions changed */
	if (width != wbs->width || height != wbs->height)
		silcpurple_wb_set_dimensions(wb, height, width);

	if (command == SILCPURPLE_WB_DRAW) {
		/* Parse data and draw it */
		ret = silc_buffer_unformat(&buf,
					   SILC_STR_UI_INT(&dx),
					   SILC_STR_UI_INT(&dy),
					   SILC_STR_END);
		if (ret < 0)
			return;
		silc_buffer_pull(&buf, 8);
		x = dx;
		y = dy;
		while (silc_buffer_len(&buf) > 0) {
			ret = silc_buffer_unformat(&buf,
						   SILC_STR_UI_INT(&dx),
						   SILC_STR_UI_INT(&dy),
						   SILC_STR_END);
			if (ret < 0)
				return;
			silc_buffer_pull(&buf, 8);

			purple_whiteboard_draw_line(wb, x, y, x + dx, y + dy,
						    brush_color, brush_size);
			x += dx;
			y += dy;
		}
	}

	if (command == SILCPURPLE_WB_CLEAR)
		purple_whiteboard_clear(wb);
}
Exemple #6
0
SilcCommandPayload silc_command_payload_parse(const unsigned char *payload,
					      SilcUInt32 payload_len)
{
  SilcBufferStruct buffer;
  SilcCommandPayload newp;
  unsigned char args_num;
  SilcUInt16 p_len;
  int ret;

  SILC_LOG_DEBUG(("Parsing command payload"));

  silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
  newp = silc_calloc(1, sizeof(*newp));
  if (!newp)
    return NULL;

  /* Parse the Command Payload */
  ret = silc_buffer_unformat(&buffer,
			     SILC_STR_UI_SHORT(&p_len),
			     SILC_STR_UI_CHAR(&newp->cmd),
			     SILC_STR_UI_CHAR(&args_num),
			     SILC_STR_UI_SHORT(&newp->ident),
			     SILC_STR_END);
  if (ret == -1) {
    SILC_LOG_ERROR(("Incorrect command payload in packet"));
    silc_free(newp);
    return NULL;
  }

  if (p_len != silc_buffer_len(&buffer)) {
    SILC_LOG_ERROR(("Incorrect command payload in packet"));
    silc_free(newp);
    return NULL;
  }

  if (newp->cmd == 0) {
    SILC_LOG_ERROR(("Incorrect command type in command payload"));
    silc_free(newp);
    return NULL;
  }

  silc_buffer_pull(&buffer, SILC_COMMAND_PAYLOAD_LEN);
  if (args_num) {
    newp->args = silc_argument_payload_parse(buffer.data,
					     silc_buffer_len(&buffer),
					     args_num);
    if (!newp->args) {
      silc_free(newp);
      return NULL;
    }
  }
  silc_buffer_push(&buffer, SILC_COMMAND_PAYLOAD_LEN);

  return newp;
}
Exemple #7
0
SilcBuffer silc_attribute_payload_encode_data(SilcBuffer attrs,
					      SilcAttribute attribute,
					      SilcAttributeFlags flags,
					      const unsigned char *data,
					      SilcUInt32 data_len)
{
  SilcBuffer buffer = attrs;
  SilcUInt32 len;

  len = 4 + (SilcUInt16)data_len;
  buffer = silc_buffer_realloc(buffer,
			       (buffer ? silc_buffer_truelen(buffer) +
				len : len));
  if (!buffer)
    return NULL;
  silc_buffer_pull(buffer, silc_buffer_len(buffer));
  silc_buffer_pull_tail(buffer, len);
  silc_buffer_format(buffer,
		     SILC_STR_UI_CHAR(attribute),
		     SILC_STR_UI_CHAR(flags),
		     SILC_STR_UI_SHORT((SilcUInt16)data_len),
		     SILC_STR_UI_XNSTRING(data, (SilcUInt16)data_len),
		     SILC_STR_END);
  silc_buffer_push(buffer, buffer->data - buffer->head);

  return buffer;
}
Exemple #8
0
SilcBuffer silc_command_payload_encode(SilcCommand cmd,
				       SilcUInt32 argc,
				       unsigned char **argv,
				       SilcUInt32 *argv_lens,
				       SilcUInt32 *argv_types,
				       SilcUInt16 ident)
{
  SilcBuffer buffer;
  SilcBuffer args = NULL;
  SilcUInt32 len = 0;

  SILC_LOG_DEBUG(("Encoding command payload"));

  if (argc) {
    args = silc_argument_payload_encode(argc, argv, argv_lens, argv_types);
    if (!args)
      return NULL;
    len = silc_buffer_len(args);
  }

  len += SILC_COMMAND_PAYLOAD_LEN;
  buffer = silc_buffer_alloc_size(len);
  if (!buffer)
    return NULL;

  /* Create Command payload */
  silc_buffer_format(buffer,
		     SILC_STR_UI_SHORT(len),
		     SILC_STR_UI_CHAR(cmd),
		     SILC_STR_UI_CHAR(argc),
		     SILC_STR_UI_SHORT(ident),
		     SILC_STR_END);

  /* Add arguments */
  if (argc) {
    silc_buffer_pull(buffer, SILC_COMMAND_PAYLOAD_LEN);
    silc_buffer_format(buffer,
		       SILC_STR_UI_XNSTRING(args->data,
					    silc_buffer_len(args)),
		       SILC_STR_END);
    silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN);
    silc_buffer_free(args);
  }

  return buffer;
}
Exemple #9
0
void silcpurple_wb_clear(PurpleWhiteboard *wb)
{
	SilcPurpleWb wbs = wb->proto_data;
	SilcBuffer packet;
	int len;
        PurpleConnection *gc;
        SilcPurple sg;

	gc = purple_account_get_connection(wb->account);
	g_return_if_fail(gc);
 	sg = gc->proto_data;
	g_return_if_fail(sg);

	len = SILCPURPLE_WB_HEADER;
	packet = silc_buffer_alloc_size(len);
	if (!packet)
		return;

	/* Assmeble packet */
	silc_buffer_format(packet,
			   SILC_STR_UI32_STRING(SILCPURPLE_WB_MIME),
			   SILC_STR_UI_CHAR(SILCPURPLE_WB_CLEAR),
			   SILC_STR_UI_SHORT(wbs->width),
			   SILC_STR_UI_SHORT(wbs->height),
			   SILC_STR_UI_INT(wbs->brush_color),
			   SILC_STR_UI_SHORT(wbs->brush_size),
			   SILC_STR_END);

	/* Send the message */
	if (wbs->type == 0) {
		/* Private message */
		silc_client_send_private_message(sg->client, sg->conn,
						 wbs->u.client,
						 SILC_MESSAGE_FLAG_DATA, NULL,
						 packet->head, len);
	} else if (wbs->type == 1) {
		/* Channel message */
		silc_client_send_channel_message(sg->client, sg->conn,
						 wbs->u.channel, NULL,
						 SILC_MESSAGE_FLAG_DATA, NULL,
						 packet->head, len);
	}

	silc_buffer_free(packet);
}
Exemple #10
0
SilcBuffer silc_command_payload_encode_payload(SilcCommandPayload payload)
{
  SilcBuffer buffer;
  SilcBuffer args = NULL;
  SilcUInt32 len = 0;
  SilcUInt32 argc = 0;

  SILC_LOG_DEBUG(("Encoding command payload"));

  if (payload->args) {
    args = silc_argument_payload_encode_payload(payload->args);
    if (args)
      len = silc_buffer_len(args);
    argc = silc_argument_get_arg_num(payload->args);
  }

  len += SILC_COMMAND_PAYLOAD_LEN;
  buffer = silc_buffer_alloc_size(len);
  if (!buffer) {
    if (args)
      silc_buffer_free(args);
    return NULL;
  }

  /* Create Command payload */
  silc_buffer_format(buffer,
		     SILC_STR_UI_SHORT(len),
		     SILC_STR_UI_CHAR(payload->cmd),
		     SILC_STR_UI_CHAR(argc),
		     SILC_STR_UI_SHORT(payload->ident),
		     SILC_STR_END);

  /* Add arguments */
  if (args) {
    silc_buffer_pull(buffer, SILC_COMMAND_PAYLOAD_LEN);
    silc_buffer_format(buffer,
		       SILC_STR_UI_XNSTRING(args->data,
					    silc_buffer_len(args)),
		       SILC_STR_END);
    silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN);
    silc_buffer_free(args);
  }

  return buffer;
}
Exemple #11
0
SilcNotifyPayload silc_notify_payload_parse(const unsigned char *payload,
					    SilcUInt32 payload_len)
{
  SilcBufferStruct buffer;
  SilcNotifyPayload newp;
  SilcUInt16 len;
  int ret;

  SILC_LOG_DEBUG(("Parsing Notify payload"));

  silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
  newp = silc_calloc(1, sizeof(*newp));
  if (!newp)
    return NULL;

  ret = silc_buffer_unformat(&buffer,
			     SILC_STR_UI_SHORT(&newp->type),
			     SILC_STR_UI_SHORT(&len),
			     SILC_STR_UI_CHAR(&newp->argc),
			     SILC_STR_END);
  if (ret == -1)
    goto err;

  if (len > silc_buffer_len(&buffer))
    goto err;

  if (newp->argc) {
    silc_buffer_pull(&buffer, 5);
    newp->args = silc_argument_payload_parse(buffer.data,
					     silc_buffer_len(&buffer),
					     newp->argc);
    if (!newp->args)
      goto err;
    silc_buffer_push(&buffer, 5);
  }

  return newp;

 err:
  silc_free(newp);
  return NULL;
}
Exemple #12
0
static SilcBool
silc_client_send_private_message_key_request(SilcClient client,
					     SilcClientConnection conn,
					     SilcClientEntry client_entry)
{
  const char *cipher, *hmac;

  SILC_LOG_DEBUG(("Sending private message key request"));

  cipher = silc_cipher_get_name(client_entry->internal.send_key);
  hmac = silc_hmac_get_name(client_entry->internal.hmac_send);

  /* Send the packet */
  return silc_packet_send_va_ext(conn->stream,
				 SILC_PACKET_PRIVATE_MESSAGE_KEY,
				 0, 0, NULL, SILC_ID_CLIENT,
				 &client_entry->id, NULL, NULL,
				 SILC_STR_UI_SHORT(strlen(cipher)),
				 SILC_STR_DATA(cipher, strlen(cipher)),
				 SILC_STR_UI_SHORT(strlen(hmac)),
				 SILC_STR_DATA(hmac, strlen(hmac)),
				 SILC_STR_END);
}
Exemple #13
0
unsigned char *silc_attribute_get_verify_data(SilcDList attrs,
					      SilcBool server_verification,
					      SilcUInt32 *data_len)
{
  SilcAttributePayload attr;
  SilcBufferStruct buffer;
  unsigned char *data = NULL;
  SilcUInt32 len = 0;

  silc_dlist_start(attrs);
  while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) {
    switch (attr->attribute) {
    case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
      /* Server signature is never part of the verification data */
      break;

    case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
      /* For user signature verification this is not part of the data */
      if (!server_verification)
	break;

      /* Fallback, for server signature verification, user digital signature
	 is part of verification data. */

    default:
      /* All other data is part of the verification data */
      data = silc_realloc(data, sizeof(*data) * (4 + attr->data_len + len));
      if (!data)
	return NULL;
      silc_buffer_set(&buffer, data + len, 4 + attr->data_len);
      silc_buffer_format(&buffer,
			 SILC_STR_UI_CHAR(attr->attribute),
			 SILC_STR_UI_CHAR(attr->flags),
			 SILC_STR_UI_SHORT(attr->data_len),
			 SILC_STR_UI_XNSTRING(attr->data, attr->data_len),
			 SILC_STR_END);
      len += 4 + attr->data_len;
      break;
    }
  }

  if (data_len)
    *data_len = len;

  return data;
}
Exemple #14
0
static unsigned char *
silc_attribute_payload_encode_int(SilcAttribute attribute,
				  SilcAttributeFlags flags,
				  void *object,
				  SilcUInt32 object_size,
				  SilcUInt32 *ret_len)
{
  SilcBuffer tmpbuf = NULL;
  unsigned char tmp[4], *str = NULL, *ret;
  SilcUInt32 len;

  /* Encode according to attribute type */
  if (flags & SILC_ATTRIBUTE_FLAG_VALID) {
    if (!object && !object_size)
      return NULL;

    switch (attribute) {

    case SILC_ATTRIBUTE_USER_INFO:
      {
	SilcVCard vcard = object;
	if (object_size != sizeof(*vcard))
	  return NULL;
	str = silc_vcard_encode(vcard, &object_size);
	if (!str)
	  return NULL;
	object = str;
      }
      break;

    case SILC_ATTRIBUTE_SERVICE:
      {
	SilcAttributeObjService *service = object;
	SilcUInt32 len2;
	if (object_size != sizeof(*service))
	  return NULL;
	len = strlen(service->address);
	len2 = strlen(service->signon);
	tmpbuf = silc_buffer_alloc_size(13 + len + len2);
	if (!tmpbuf)
	  return NULL;
	silc_buffer_format(tmpbuf,
			   SILC_STR_UI_INT(service->port),
			   SILC_STR_UI_SHORT(len),
			   SILC_STR_UI_XNSTRING(service->address, len),
			   SILC_STR_UI_CHAR(service->status),
			   SILC_STR_UI_SHORT(len2),
			   SILC_STR_UI_XNSTRING(service->signon, len2),
			   SILC_STR_UI_INT(service->idle),
			   SILC_STR_END);
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_STATUS_MOOD:
    case SILC_ATTRIBUTE_PREFERRED_CONTACT:
      {
	SilcUInt32 mask = SILC_PTR_TO_32(object);
	if (object_size != sizeof(SilcUInt32))
	  return NULL;
	SILC_PUT32_MSB(mask, tmp);
	object = tmp;
	object_size = sizeof(SilcUInt32);
      }
      break;

    case SILC_ATTRIBUTE_STATUS_FREETEXT:
    case SILC_ATTRIBUTE_PREFERRED_LANGUAGE:
    case SILC_ATTRIBUTE_TIMEZONE:
      {
	unsigned char *string = object;
	str = silc_malloc(2 + object_size);
	if (!str)
	  return NULL;
	SILC_PUT16_MSB(object_size, str);
	memcpy(str + 2, string, object_size);
	object = str;
	object_size += 2;
      }
      break;

    case SILC_ATTRIBUTE_STATUS_MESSAGE:
    case SILC_ATTRIBUTE_EXTENSION:
    case SILC_ATTRIBUTE_USER_ICON:
      {
	SilcMime mime = object;
	if (object_size != sizeof(*mime))
	  return NULL;
	str = silc_mime_encode(mime, &object_size);
	if (!str)
	  return NULL;
	object = str;
      }
      break;

    case SILC_ATTRIBUTE_GEOLOCATION:
      {
	SilcAttributeObjGeo *geo = object;
	SilcUInt32 len1, len2, len3, len4;
	if (object_size != sizeof(*geo))
	  return NULL;
	len1 = (geo->longitude ? strlen(geo->longitude) : 0);
	len2 = (geo->latitude  ? strlen(geo->latitude)  : 0);
	len3 = (geo->altitude  ? strlen(geo->altitude)  : 0);
	len4 = (geo->accuracy  ? strlen(geo->accuracy)  : 0);
	if (len1 + len2 + len3 + len4 == 0)
	  return NULL;
	len = len1 + len2 + len3 + len4;
	tmpbuf = silc_buffer_alloc_size(8 + len);
	if (!tmpbuf)
	  return NULL;
	silc_buffer_format(tmpbuf,
			   SILC_STR_UI_SHORT(len1),
			   SILC_STR_UI16_STRING(len1 ? geo->longitude : ""),
			   SILC_STR_UI_SHORT(len2),
			   SILC_STR_UI16_STRING(len2 ? geo->latitude : ""),
			   SILC_STR_UI_SHORT(len3),
			   SILC_STR_UI16_STRING(len3 ? geo->altitude : ""),
			   SILC_STR_UI_SHORT(len4),
			   SILC_STR_UI16_STRING(len4 ? geo->accuracy : ""),
			   SILC_STR_END);
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_DEVICE_INFO:
      {
	SilcAttributeObjDevice *dev = object;
	SilcUInt32 len1, len2, len3, len4;
	if (object_size != sizeof(*dev))
	  return NULL;
	len1 = (dev->manufacturer ? strlen(dev->manufacturer) : 0);
	len2 = (dev->version      ? strlen(dev->version)      : 0);
	len3 = (dev->model        ? strlen(dev->model)        : 0);
	len4 = (dev->language     ? strlen(dev->language)     : 0);
	if (len1 + len2 + len3 + len4 == 0)
	  return NULL;
	len = len1 + len2 + len3 + len4;
	tmpbuf = silc_buffer_alloc_size(4 + 8 + len);
	if (!tmpbuf)
	  return NULL;
	silc_buffer_format(tmpbuf,
			   SILC_STR_UI_INT(dev->type),
			   SILC_STR_UI_SHORT(len1),
			   SILC_STR_UI16_STRING(len1 ? dev->manufacturer : ""),
			   SILC_STR_UI_SHORT(len2),
			   SILC_STR_UI16_STRING(len2 ? dev->version : ""),
			   SILC_STR_UI_SHORT(len3),
			   SILC_STR_UI16_STRING(len3 ? dev->model : ""),
			   SILC_STR_UI_SHORT(len4),
			   SILC_STR_UI16_STRING(len4 ? dev->language : ""),
			   SILC_STR_END);
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_PHONE_NUMBER:
      {
	SilcAttributeObjPN *pn = object;
	if (object_size != sizeof(*pn))
	  return NULL;
	if (!pn->number || strlen(pn->number) < 5)
	  return NULL;
	tmpbuf = silc_buffer_alloc(0);
	if (!tmpbuf)
	  return NULL;
	if (silc_buffer_format(tmpbuf,
			       SILC_STR_UI_INT(pn->format),
			       SILC_STR_UI_SHORT(strlen(pn->number)),
			       SILC_STR_UI16_STRING(pn->number),
			       SILC_STR_END) < 0)
	  return NULL;
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
    case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
      {
	SilcAttributeObjPk *pk = object;
	if (object_size != sizeof(*pk))
	  return NULL;
	len = (pk->type ? strlen(pk->type) : 0);
	tmpbuf = silc_buffer_alloc_size(2 + len + pk->data_len);
	if (!tmpbuf)
	  return NULL;
	silc_buffer_format(tmpbuf,
			   SILC_STR_UI_SHORT(len),
			   SILC_STR_UI16_STRING(pk->type),
			   SILC_STR_UI_XNSTRING(pk->data, pk->data_len),
			   SILC_STR_END);
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
    case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
      {
	SilcAttributeObjPk *pk = object;
	if (object_size != sizeof(*pk))
	  return NULL;
	object = pk->data;
	object_size = pk->data_len;
      }
      break;

    default:
      return NULL;
      break;
    }

    ret = silc_memdup(object, object_size);

    if (tmpbuf)
      silc_buffer_free(tmpbuf);
    silc_free(str);

    if (ret_len)
      *ret_len = object_size;

    return ret;
  }

  return NULL;
}
Exemple #15
0
SilcBuffer silc_notify_payload_encode(SilcNotifyType type, SilcUInt32 argc,
				      va_list ap)
{
  SilcBuffer buffer;
  SilcBuffer args = NULL;
  unsigned char **argv;
  SilcUInt32 *argv_lens = NULL, *argv_types = NULL;
  unsigned char *x;
  SilcUInt32 x_len, len = 0;
  int i, k = 0;

  if (argc) {
    argv = silc_calloc(argc, sizeof(unsigned char *));
    if (!argv)
      return NULL;
    argv_lens = silc_calloc(argc, sizeof(SilcUInt32));
    if (!argv_lens) {
      silc_free(argv);
      return NULL;
    }
    argv_types = silc_calloc(argc, sizeof(SilcUInt32));
    if (!argv_types) {
      silc_free(argv_lens);
      silc_free(argv);
      return NULL;
    }

    for (i = 0, k = 0; i < argc; i++) {
      x = va_arg(ap, unsigned char *);
      x_len = va_arg(ap, SilcUInt32);

      if (!x || !x_len)
	continue;

      argv[k] = silc_memdup(x, x_len);
      if (!argv[k])
	return NULL;
      argv_lens[k] = x_len;
      argv_types[k] = i + 1;
      k++;
    }

    args = silc_argument_payload_encode(k, argv, argv_lens, argv_types);
    len = silc_buffer_len(args);

    for (i = 0; i < k; i++)
      silc_free(argv[i]);
    silc_free(argv);
    silc_free(argv_lens);
    silc_free(argv_types);
  }

  len += 5;
  buffer = silc_buffer_alloc_size(len);
  if (!buffer)
    return NULL;
  silc_buffer_format(buffer,
		     SILC_STR_UI_SHORT(type),
		     SILC_STR_UI_SHORT(len),
		     SILC_STR_UI_CHAR(k),
		     SILC_STR_END);

  if (k) {
    silc_buffer_format(buffer,
		       SILC_STR_OFFSET(5),
		       SILC_STR_DATA(args->data, silc_buffer_len(args)),
		       SILC_STR_END);
    silc_buffer_free(args);
  }

  return buffer;
}