Esempio n. 1
0
struct tlv *dol_process(const struct tlv *tlv, const struct tlvdb *tlvdb, tlv_tag_t tag)
{
	size_t res_len;
	if (!tlv || !(res_len = dol_calculate_len(tlv, 0))) {
		struct tlv *res_tlv = malloc(sizeof(*res_tlv));

		res_tlv->tag = tag;
		res_tlv->len = 0;
		res_tlv->value = NULL;

		return res_tlv;
	}

	struct tlv *res_tlv = malloc(sizeof(*res_tlv) + res_len);
	if (!res_tlv)
		return NULL;

	const unsigned char *buf = tlv->value;
	size_t left = tlv->len;
	unsigned char *res = (unsigned char *)(res_tlv + 1);
	size_t pos = 0;

	while (left) {
		struct tlv cur_tlv;
		if (!tlv_parse_tl(&buf, &left, &cur_tlv) || pos + cur_tlv.len > res_len) {
			free(res_tlv);

			return NULL;
		}

		const struct tlv *tag_tlv = tlvdb_get(tlvdb, cur_tlv.tag, NULL);
		if (!tag_tlv) {
			memset(res + pos, 0, cur_tlv.len);
		} else if (tag_tlv->len > cur_tlv.len) {
			memcpy(res + pos, tag_tlv->value, cur_tlv.len);
		} else {
			// FIXME: cn data should be padded with 0xFF !!!
			memcpy(res + pos, tag_tlv->value, tag_tlv->len);
			memset(res + pos + tag_tlv->len, 0, cur_tlv.len - tag_tlv->len);
		}
		pos += cur_tlv.len;
	}

	res_tlv->tag = tag;
	res_tlv->len = res_len;
	res_tlv->value = res;

	return res_tlv;
}
Esempio n. 2
0
unsigned char *dol_process(const struct tlv *tlv, const struct tlvdb *tlvdb, size_t *len)
{
	if (!tlv) {
		*len = 0;
		return NULL;
	}

	const unsigned char *buf = tlv->value;
	size_t left = tlv->len;
	size_t res_len = dol_calculate_len(tlv, 0);
	unsigned char *res;
	size_t pos = 0;

	if (!res_len) {
		*len = 0;
		return NULL;
	}

	res = malloc(res_len);

	while (left) {
		struct tlv cur_tlv;
		if (!tlv_parse_tl(&buf, &left, &cur_tlv) || pos + cur_tlv.len > res_len) {
			free(res);
			return NULL;
		}

		const struct tlv *tag_tlv = tlvdb_get(tlvdb, cur_tlv.tag, NULL);
		if (!tag_tlv) {
			memset(res + pos, 0, cur_tlv.len);
		} else if (tag_tlv->len > cur_tlv.len) {
			memcpy(res + pos, tag_tlv->value, cur_tlv.len);
		} else {
			// FIXME: cn data should be padded with 0xFF !!!
			memcpy(res + pos, tag_tlv->value, tag_tlv->len);
			memset(res + pos + tag_tlv->len, 0, cur_tlv.len - tag_tlv->len);
		}
		pos += cur_tlv.len;
	}

	*len = pos;

	return res;
}
Esempio n. 3
0
struct tlvdb *dol_parse(const struct tlv *tlv, const unsigned char *data, size_t data_len)
{
	if (!tlv)
		return NULL;

	const unsigned char *buf = tlv->value;
	size_t left = tlv->len;
	size_t res_len = dol_calculate_len(tlv, data_len);
	size_t pos = 0;
	struct tlvdb *db = NULL;

	if (res_len != data_len)
		return NULL;

	while (left) {
		struct tlv cur_tlv;
		if (!tlv_parse_tl(&buf, &left, &cur_tlv) || pos + cur_tlv.len > res_len) {
			tlvdb_free(db);
			return NULL;
		}

		/* Last tag can be of variable length */
		if (cur_tlv.len == 0 && left == 0)
			cur_tlv.len = res_len - pos;

		struct tlvdb *tag_db = tlvdb_fixed(cur_tlv.tag, cur_tlv.len, data + pos);
		if (!db)
			db = tag_db;
		else
			tlvdb_add(db, tag_db);

		pos += cur_tlv.len;
	}

	return db;
}