Created SILC Crypto Toolkit git repository.
[crypto.git] / lib / silccore / silcattrs.c
diff --git a/lib/silccore/silcattrs.c b/lib/silccore/silcattrs.c
deleted file mode 100644 (file)
index d40e53a..0000000
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
-
-  silcattrs.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2002 - 2007 Pekka Riikonen
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; version 2 of the License.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-*/
-/* Implementation of Attribute Payload routines */
-/* $Id$ */
-
-#include "silc.h"
-#include "silcattrs.h"
-
-/******************************************************************************
-
-                             Attribute Payload
-
-******************************************************************************/
-
-struct SilcAttributePayloadStruct {
-  SilcAttribute attribute;
-  SilcAttributeFlags flags;
-  SilcUInt16 data_len;
-  unsigned char *data;
-};
-
-/* Internal routine for encoding a attribute */
-
-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:
-      {
-#ifdef SILC_DIST_VCARD
-       SilcVCard vcard = object;
-       if (object_size != sizeof(*vcard))
-         return NULL;
-       str = silc_vcard_encode(vcard, &object_size);
-       if (!str)
-         return NULL;
-       object = str;
-#endif /* SILC_DIST_VCARD */
-      }
-      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;
-}
-
-/* Allocates attribute payload and encodes the attribute there */
-
-SilcAttributePayload silc_attribute_payload_alloc(SilcAttribute attribute,
-                                                 SilcAttributeFlags flags,
-                                                 void *object,
-                                                 SilcUInt32 object_size)
-{
-  SilcAttributePayload attr;
-  SilcUInt32 tmp_len;
-
-  attr = silc_calloc(1, sizeof(*attr));
-  if (!attr)
-    return NULL;
-
-  attr->attribute = attribute;
-  attr->flags = flags;
-  attr->data =
-    silc_attribute_payload_encode_int(attribute, flags, object,
-                                     object_size, &tmp_len);
-  attr->data_len = (SilcUInt16)tmp_len;
-  if (!attr->data) {
-    silc_free(attr);
-    return NULL;
-  }
-
-  return attr;
-}
-
-/* Parse list of payloads */
-
-SilcDList silc_attribute_payload_parse(const unsigned char *payload,
-                                      SilcUInt32 payload_len)
-{
-  SilcBufferStruct buffer;
-  SilcDList list;
-  SilcAttributePayload newp;
-  SilcUInt32 len;
-  int ret;
-
-  SILC_LOG_DEBUG(("Parsing Attribute Payload list"));
-
-  silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
-  list = silc_dlist_init();
-
-  while (silc_buffer_len(&buffer)) {
-    newp = silc_calloc(1, sizeof(*newp));
-    if (!newp)
-      goto err;
-    ret = silc_buffer_unformat(&buffer,
-                              SILC_STR_UI_CHAR(&newp->attribute),
-                              SILC_STR_UI_CHAR(&newp->flags),
-                              SILC_STR_UI16_NSTRING_ALLOC(&newp->data,
-                                                          &newp->data_len),
-                              SILC_STR_END);
-    if (ret == -1)
-      goto err;
-
-    if (newp->data_len > silc_buffer_len(&buffer) - 4) {
-      SILC_LOG_ERROR(("Incorrect attribute payload in list"));
-      goto err;
-    }
-
-    len = 4 + newp->data_len;
-    if (silc_buffer_len(&buffer) < len)
-      break;
-    silc_buffer_pull(&buffer, len);
-
-    silc_dlist_add(list, newp);
-  }
-
-  return list;
-
- err:
-  silc_attribute_payload_list_free(list);
-  return NULL;
-}
-
-/* Encode one attribute payload to buffer */
-
-SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs,
-                                        SilcAttribute attribute,
-                                        SilcAttributeFlags flags,
-                                        void *object,
-                                        SilcUInt32 object_size)
-{
-  object = silc_attribute_payload_encode_int(attribute, flags, object,
-                                            object_size, &object_size);
-  attrs = silc_attribute_payload_encode_data(attrs, attribute, flags,
-                                            (const unsigned char *)object,
-                                            object_size);
-  silc_free(object);
-  return attrs;
-}
-
-/* Encoded the attribute data directly to buffer */
-
-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;
-}
-
-/* Free Attribute Payload */
-
-void silc_attribute_payload_free(SilcAttributePayload payload)
-{
-  silc_free(payload->data);
-  silc_free(payload);
-}
-
-/* Free's list of Attribute Payloads */
-
-void silc_attribute_payload_list_free(SilcDList list)
-{
-  SilcAttributePayload entry;
-
-  silc_dlist_start(list);
-  while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
-    silc_attribute_payload_free(entry);
-    silc_dlist_del(list, entry);
-  }
-
-  silc_dlist_uninit(list);
-}
-
-/* Return attribute type */
-
-SilcAttribute silc_attribute_get_attribute(SilcAttributePayload payload)
-{
-  return payload->attribute;
-}
-
-/* Return attribute flags */
-
-SilcAttributeFlags silc_attribute_get_flags(SilcAttributePayload payload)
-{
-  return payload->flags;
-}
-
-/* Return attribute data from the payload */
-
-const unsigned char *silc_attribute_get_data(SilcAttributePayload payload,
-                                            SilcUInt32 *data_len)
-{
-  if (data_len)
-    *data_len = (SilcUInt32)payload->data_len;
-  return (const unsigned char *)payload->data;
-}
-
-/* Construct digital signature verification data */
-
-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;
-}
-
-/* Return parsed attribute object */
-
-SilcBool silc_attribute_get_object(SilcAttributePayload payload,
-                                  void *object, SilcUInt32 object_size)
-{
-  SilcUInt16 len;
-  SilcBool ret = FALSE;
-
-  if (!object || payload->flags & SILC_ATTRIBUTE_FLAG_INVALID)
-    return FALSE;
-
-  switch (payload->attribute) {
-  case SILC_ATTRIBUTE_USER_INFO:
-    {
-#ifdef SILC_DIST_VCARD
-      SilcVCard vcard = object;
-      if (object_size != sizeof(*vcard))
-       break;
-      if (!silc_vcard_decode(payload->data, payload->data_len, vcard))
-       break;
-      ret = TRUE;
-#endif /* SILC_DIST_VCARD */
-    }
-    break;
-
-  case SILC_ATTRIBUTE_SERVICE:
-    {
-      SilcAttributeObjService *service = object;
-      SilcBufferStruct buf;
-      SilcUInt16 addr_len, signon_len;
-      char *addr, *signon;
-      int res;
-      if (object_size != sizeof(*service))
-       break;
-      if (payload->data_len < 13)
-       break;
-      silc_buffer_set(&buf, payload->data, payload->data_len);
-      res = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&service->port),
-                                SILC_STR_UI16_NSTRING(&addr, &addr_len),
-                                SILC_STR_UI_CHAR(&service->status),
-                                SILC_STR_UI16_NSTRING(&signon, &signon_len),
-                                SILC_STR_UI_INT(&service->idle),
-                                SILC_STR_END);
-      if (res == -1)
-       break;
-      memset(service->address, 0, sizeof(service->address));
-      memset(service->signon, 0, sizeof(service->signon));
-      memcpy(service->address, addr,
-            (addr_len < sizeof(service->address) - 1 ? addr_len :
-             sizeof(service->address) - 1));
-      memcpy(service->signon, signon,
-            (signon_len < sizeof(service->signon) - 1 ? signon_len :
-             sizeof(service->signon) - 1));
-      ret = TRUE;
-    }
-    break;
-
-  case SILC_ATTRIBUTE_STATUS_MOOD:
-  case SILC_ATTRIBUTE_PREFERRED_CONTACT:
-    {
-      SilcUInt32 *mask = (SilcUInt32 *)object;
-      if (object_size != sizeof(SilcUInt32))
-       break;
-      if (payload->data_len < 4)
-       break;
-      SILC_GET32_MSB(*mask, payload->data);
-      ret = TRUE;
-    }
-    break;
-
-  case SILC_ATTRIBUTE_STATUS_FREETEXT:
-  case SILC_ATTRIBUTE_PREFERRED_LANGUAGE:
-  case SILC_ATTRIBUTE_TIMEZONE:
-    {
-      char *string = object;
-      if (payload->data_len < 2)
-       break;
-      SILC_GET16_MSB(len, payload->data);
-      if (payload->data_len < 2 + len)
-       break;
-      if (object_size < len)
-       break;
-      memcpy(string, payload->data + 2, len);
-      ret = TRUE;
-    }
-    break;
-
-  case SILC_ATTRIBUTE_STATUS_MESSAGE:
-  case SILC_ATTRIBUTE_EXTENSION:
-  case SILC_ATTRIBUTE_USER_ICON:
-    {
-      SilcMime mime = object;
-      if (object_size != sizeof(*mime))
-       break;
-      if (!silc_mime_decode(mime, payload->data, payload->data_len))
-       break;
-      ret = TRUE;
-    }
-    break;
-
-  case SILC_ATTRIBUTE_GEOLOCATION:
-    {
-      SilcAttributeObjGeo *geo = object;
-      SilcBufferStruct buffer;
-      int res;
-      if (object_size != sizeof(*geo))
-       break;
-      silc_buffer_set(&buffer, (unsigned char *)payload->data,
-                     payload->data_len);
-      res = silc_buffer_unformat(&buffer,
-                                SILC_STR_UI16_STRING_ALLOC(&geo->longitude),
-                                SILC_STR_UI16_STRING_ALLOC(&geo->latitude),
-                                SILC_STR_UI16_STRING_ALLOC(&geo->altitude),
-                                SILC_STR_UI16_STRING_ALLOC(&geo->accuracy),
-                                SILC_STR_END);
-      if (res == -1)
-       break;
-      ret = TRUE;
-    }
-    break;
-
-  case SILC_ATTRIBUTE_DEVICE_INFO:
-    {
-      SilcAttributeObjDevice *dev = object;
-      SilcBufferStruct buffer;
-      SilcUInt32 type;
-      int res;
-      if (object_size != sizeof(*dev))
-       break;
-      silc_buffer_set(&buffer, (unsigned char *)payload->data,
-                     payload->data_len);
-      res =
-       silc_buffer_unformat(&buffer,
-                            SILC_STR_UI_INT(&type),
-                            SILC_STR_UI16_STRING_ALLOC(&dev->manufacturer),
-                            SILC_STR_UI16_STRING_ALLOC(&dev->version),
-                            SILC_STR_UI16_STRING_ALLOC(&dev->model),
-                            SILC_STR_UI16_STRING_ALLOC(&dev->language),
-                            SILC_STR_END);
-      if (res == -1)
-       break;
-      dev->type = type;
-      ret = TRUE;
-    }
-    break;
-
-  case SILC_ATTRIBUTE_PHONE_NUMBER:
-    {
-      SilcAttributeObjPN *pn = object;
-      SilcBufferStruct buffer;
-      SilcUInt32 pn_format;
-      int res;
-      if (object_size != sizeof(*pn))
-       break;
-      silc_buffer_set(&buffer, (unsigned char *)payload->data,
-                     payload->data_len);
-      res =
-       silc_buffer_unformat(&buffer,
-                            SILC_STR_UI_INT(&pn_format),
-                            SILC_STR_UI16_STRING_ALLOC(&pn->number),
-                            SILC_STR_END);
-      if (res == -1)
-       break;
-      pn->format = pn_format;
-      ret = TRUE;
-    }
-    break;
-
-  case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
-  case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
-    {
-      SilcAttributeObjPk *pk = object;
-      SilcBufferStruct buffer;
-      int res;
-      if (object_size != sizeof(*pk))
-       break;
-      silc_buffer_set(&buffer, (unsigned char *)payload->data,
-                     payload->data_len);
-      res =
-       silc_buffer_unformat(&buffer,
-                            SILC_STR_UI16_NSTRING_ALLOC(&pk->type, &len),
-                            SILC_STR_END);
-      if (res == -1 || len > silc_buffer_len(&buffer) - 2)
-       break;
-      pk->data = silc_memdup(payload->data + 2 + len,
-                            payload->data_len - 2 - len);
-      pk->data_len = payload->data_len - 2 - len;
-      ret = TRUE;
-    }
-    break;
-
-  case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
-  case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
-    {
-      SilcAttributeObjPk *pk = object;
-      if (object_size != sizeof(*pk))
-       break;
-      pk->type = NULL;
-      pk->data = silc_memdup(payload->data, payload->data_len);
-      pk->data_len = payload->data_len;
-      ret = TRUE;
-    }
-    break;
-
-  default:
-    break;
-  }
-
-  return ret;
-}