int KSI_TlvTemplate_parse(KSI_CTX *ctx, const unsigned char *raw, unsigned raw_len, const KSI_TlvTemplate *tmpl, void *payload) { int res = KSI_UNKNOWN_ERROR; KSI_TLV *tlv = NULL; struct tlv_track_s tr[0xf]; KSI_ERR_clearErrors(ctx); if (ctx == NULL || raw == NULL || tmpl == NULL || payload == NULL) { KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } res = KSI_TLV_parseBlob2(ctx, (unsigned char *)raw, raw_len, 0, &tlv); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } res = extract(ctx, payload, tlv, tmpl, tr, 0, sizeof(tr)); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } KSI_LOG_logTlv(ctx, KSI_LOG_DEBUG, "Parsed TLV", tlv); res = KSI_OK; cleanup: KSI_TLV_free(tlv); return res; }
static void TestClone(CuTest *tc) { int res; KSI_TLV *tlv = NULL; KSI_TLV *clone = NULL; unsigned char in[0xffff + 4]; unsigned char out1[0xffff + 4]; char errstr[1024]; size_t out_len; size_t in_len; FILE *f = NULL; int i = 0; KSI_ERR_clearErrors(ctx); while (ok_sample[i] != NULL) { f = fopen(getFullResourcePath(ok_sample[i]), "rb"); CuAssert(tc, "Unable to open test file.", f != NULL); in_len = (unsigned) fread(in, 1, sizeof(in), f); fclose(f); f = NULL; res = KSI_TLV_parseBlob2(ctx, in, in_len, 0, &tlv); CuAssert(tc, "Unable to parse TLV.", res == KSI_OK); res = parseStructure(tlv, 0); CuAssert(tc, "Unable to parse TLV structure.", res == KSI_OK); res = KSI_TLV_clone(tlv, &clone); CuAssert(tc, "Unsable to clone TLV.", res == KSI_OK && clone != NULL); /* Re assemble TLV */ res = KSI_TLV_serialize_ex(clone, out1, sizeof(out1), &out_len); CuAssert(tc, "Unable to serialize TLV.", res == KSI_OK); CuAssert(tc, "Serialized TLV size mismatch.", in_len == out_len); sprintf(errstr, "Serialised TLV content does not match original: '%s'.", ok_sample[i]); CuAssert(tc, errstr, !memcmp(in, out1, in_len)); KSI_TLV_free(clone); clone = NULL; KSI_TLV_free(tlv); tlv = NULL; i++; } }
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; }