+ 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 = tmpbuf->len;
+ }
+ 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 = tmpbuf->len;
+ }
+ 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 = tmpbuf->len;
+ }
+ 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;
+ }