Esempio n. 1
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;
}
Esempio n. 2
0
SilcSFTPPacket silc_sftp_packet_decode(SilcBuffer packet,
				       unsigned char **payload,
				       SilcUInt32 *payload_len)
{
  SilcUInt32 len;
  SilcUInt8 type;
  int ret;

  ret = silc_buffer_unformat(packet,
			     SILC_STR_UI_INT(&len),
			     SILC_STR_UI_CHAR(&type),
			     SILC_STR_END);
  if (ret < 0)
    return 0;

  if (type < SILC_SFTP_INIT || type > SILC_SFTP_EXTENDED_REPLY)
    return 0;

  if (len > (silc_buffer_len(packet) - 5))
    return -1;

  silc_buffer_pull(packet, 5);
  ret = silc_buffer_unformat(packet,
			     SILC_STR_UI_XNSTRING(payload, len),
			     SILC_STR_END);
  if (ret < 0)
    return 0;

  silc_buffer_push(packet, 5);

  *payload_len = len;

  return (SilcSFTPPacket)type;
}
Esempio n. 3
0
static void silc_sftp_server_handle(SilcSFTP sftp,
				    SilcSFTPStatus status,
				    SilcSFTPHandle handle,
				    void *context)
{
  SilcSFTPServer server = (SilcSFTPServer)sftp;
  SilcUInt32 id = SILC_PTR_TO_32(context);
  unsigned char *hdata;
  SilcUInt32 hdata_len;

  SILC_LOG_DEBUG(("Handle callback"));
  SILC_LOG_DEBUG(("Request ID: %d", id));

  if (status != SILC_SFTP_STATUS_OK) {
    silc_sftp_send_error(server, status, id);
    return;
  }

  hdata = server->fs->fs->sftp_encode_handle(server->fs->fs_context, sftp,
					     handle, &hdata_len);
  if (!hdata) {
    silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id);
    return;
  }

  silc_sftp_send_packet(server, SILC_SFTP_HANDLE, 8 + hdata_len,
			SILC_STR_UI_INT(id),
			SILC_STR_UI_INT(hdata_len),
			SILC_STR_UI_XNSTRING(hdata, hdata_len),
			SILC_STR_END);
}
Esempio n. 4
0
static SilcBool silc_connauth_get_signature(SilcConnAuth connauth,
					    unsigned char **auth_data,
					    SilcUInt32 *auth_data_len)
{
  int len;
  SilcSKE ske;
  SilcPrivateKey private_key;
  SilcBuffer auth;

  SILC_LOG_DEBUG(("Compute signature"));

  ske = connauth->ske;
  private_key = connauth->auth_data;

  /* Make the authentication data. Protocol says it is HASH plus
     KE Start Payload. */
  len = ske->hash_len + silc_buffer_len(ske->start_payload_copy);
  auth = silc_buffer_alloc_size(len);
  if (!auth)
    return FALSE;
  silc_buffer_format(auth,
		     SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
		     SILC_STR_UI_XNSTRING(
			       ske->start_payload_copy->data,
			       silc_buffer_len(ske->start_payload_copy)),
		     SILC_STR_END);

  len = ((silc_pkcs_private_key_get_len(private_key) + 7) / 8) + 1;
  *auth_data = silc_calloc(len, sizeof(**auth_data));
  if (*auth_data == NULL) {
    silc_buffer_free(auth);
    return FALSE;
  }

  /* Compute signature */
  if (!silc_pkcs_sign(private_key, auth->data, silc_buffer_len(auth),
		      *auth_data, len, auth_data_len, TRUE, ske->prop->hash)) {
    silc_free(*auth_data);
    silc_buffer_free(auth);
    return FALSE;
  }

  silc_buffer_free(auth);
  return TRUE;
}
Esempio n. 5
0
static SilcBool silc_connauth_verify_signature(SilcConnAuth connauth,
					       SilcPublicKey pub_key,
					       unsigned char *sign,
					       SilcUInt32 sign_len)
{
  int len;
  SilcBuffer auth;
  SilcSKE ske = connauth->ske;

  if (!pub_key || !sign)
    return FALSE;

  /* Make the authentication data. Protocol says it is HASH plus
     KE Start Payload. */
  len = ske->hash_len + silc_buffer_len(ske->start_payload_copy);
  auth = silc_buffer_alloc_size(len);
  if (!auth)
    return FALSE;
  silc_buffer_format(auth,
		     SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
		     SILC_STR_UI_XNSTRING(
				  ske->start_payload_copy->data,
				  silc_buffer_len(ske->start_payload_copy)),
		     SILC_STR_END);

  /* Verify signature */
  if (!silc_pkcs_verify(pub_key, sign, sign_len, auth->data,
			silc_buffer_len(auth), ske->prop->hash)) {
    silc_buffer_free(auth);
    return FALSE;
  }

  silc_buffer_free(auth);

  return TRUE;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
0
static void silc_sftp_server_extended(SilcSFTP sftp,
				      SilcSFTPStatus status,
				      const unsigned char *data,
				      SilcUInt32 data_len,
				      void *context)
{
  SilcSFTPServer server = (SilcSFTPServer)sftp;
  SilcUInt32 id = SILC_PTR_TO_32(context);

  SILC_LOG_DEBUG(("Extended callback"));
  SILC_LOG_DEBUG(("Request ID: %d", id));

  if (status != SILC_SFTP_STATUS_OK) {
    silc_sftp_send_error(server, status, id);
    return;
  }

  silc_sftp_send_packet(server, SILC_SFTP_EXTENDED, 4 + data_len,
			SILC_STR_UI_INT(id),
			SILC_STR_UI_XNSTRING(data, data_len),
			SILC_STR_END);
}
Esempio n. 10
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;
}