Example #1
0
int KSI_FTLV_memReadN(const unsigned char *buf, size_t buf_len, KSI_FTLV *arr, size_t arr_len, size_t *rd) {
	int res = KSI_UNKNOWN_ERROR;
	const unsigned char *ptr = buf;
	size_t len = buf_len;
	size_t i = 0;
	/* Dummy buffer, used if arr == NULL. */
	KSI_FTLV dummy;
	size_t off = 0;

	if (buf == NULL || buf_len == 0 || (arr != NULL && arr_len == 0) || (arr == NULL && arr_len != 0)) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	/* Read up-to arr_len tlvs from the buffer. */
	while ((arr_len == 0 || i < arr_len) && len > 0) {
		size_t tlvLen;
		KSI_FTLV *target = (arr == NULL ? &dummy : &arr[i]);

		/* Read the next tlv. */
		res = KSI_FTLV_memRead(ptr, len, target);
		if (res != KSI_OK) goto cleanup;

		target->off = off;

		/* Calculate consumed bytes. */
		tlvLen = target->hdr_len + target->dat_len;

		ptr += tlvLen;
		len -= tlvLen;
		off += tlvLen;
		++i;
	}

	/* If the output variable is set, evaluate it. */
	if (rd != NULL) {
		*rd = i;
	}

	res = KSI_OK;

cleanup:

	return res;
}
Example #2
0
static int generateNextTlv(struct generator_st *gen, KSI_TLV **tlv) {
	int res = KSI_UNKNOWN_ERROR;
	unsigned char *buf = NULL;
	size_t consumed = 0;
	KSI_FTLV ftlv;

	if (gen == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}


	if (gen->tlv != NULL) {
		KSI_TLV_free(gen->tlv);
		gen->tlv = NULL;
	}

	/* Try to parse only when there is something left to parse. */
	if (gen->len > 0) {
		memset(&ftlv, 0, sizeof(ftlv));
		res = KSI_FTLV_memRead(gen->ptr, gen->len, &ftlv);
		if (res != KSI_OK) {
			KSI_pushError(gen->ctx, res, NULL);
			goto cleanup;
		}

		consumed = ftlv.hdr_len + ftlv.dat_len;

		buf = KSI_malloc(consumed);
		if (buf == NULL) {
			KSI_pushError(gen->ctx, res = KSI_OUT_OF_MEMORY, NULL);
			goto cleanup;
		}

		memcpy(buf, gen->ptr, consumed);

		gen->ptr += consumed;
		gen->len -= consumed;

		/* Make sure the buffer is not overflowing. */
		if (consumed > UINT_MAX){
			KSI_pushError(gen->ctx, res = KSI_INVALID_FORMAT, "Input too large.");
			goto cleanup;
		}

		if (consumed > 0) {
			if (gen->hasSignature) {
				/* The signature must be the last element. */
				KSI_pushError(gen->ctx, res = KSI_INVALID_FORMAT, "The signature must be the last element.");
				goto cleanup;
			}

			res = KSI_TLV_parseBlob2(gen->ctx, buf, (unsigned)consumed, 1, &gen->tlv);
			if (res != KSI_OK) {
				KSI_pushError(gen->ctx, res, NULL);
				goto cleanup;
			}

			buf = NULL;

			if (KSI_TLV_getTag(gen->tlv) == 0x0704) {
				gen->sig_offset = gen->offset;
				gen->hasSignature = true;
			}
		}

	}

	gen->offset += consumed;
	*tlv = gen->tlv;

	res = KSI_OK;

cleanup:

	KSI_free(buf);

	return res;
}