int sha256_done(sha256_state * md, unsigned char *out) { int i; if (md->curlen >= sizeof(md->buf)) return FALSE; /* increase the length of the message */ md->length += md->curlen * 8; /* append the '1' bit */ md->buf[md->curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->curlen > 56) { while (md->curlen < 64) { md->buf[md->curlen++] = (unsigned char)0; } sha256_transform(md->state, md->buf); md->curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->curlen < 56) { md->buf[md->curlen++] = (unsigned char)0; } /* store length */ SILC_PUT64_MSB(md->length, md->buf + 56); sha256_transform(md->state, md->buf); /* copy output */ for (i = 0; i < 8; i += 2) { SILC_PUT32_MSB(md->state[i], out + (4 * i)); SILC_PUT32_MSB(md->state[i + 1], out + (4 * (i + 1))); } return TRUE; }
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; }