int KSI_TlvTemplate_serializeObject(KSI_CTX *ctx, const void *obj, unsigned tag, int isNc, int isFwd, const KSI_TlvTemplate *tmpl, unsigned char **raw, unsigned *raw_len) { int res = KSI_UNKNOWN_ERROR; KSI_TLV *tlv = NULL; unsigned char *tmp = NULL; unsigned tmp_len = 0; KSI_ERR_clearErrors(ctx); if (ctx == NULL || obj == NULL || tmpl == NULL || raw == NULL || raw_len == NULL) { KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } /* Create TLV for the PDU object. */ res = KSI_TLV_new(ctx, KSI_TLV_PAYLOAD_TLV, tag, isFwd, isNc, &tlv); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } /* Evaluate the TLV. */ res = KSI_TlvTemplate_construct(ctx, tlv, obj, tmpl); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } KSI_LOG_logTlv(ctx, KSI_LOG_DEBUG, "Serializing object", tlv); /* Serialize the TLV. */ res = KSI_TLV_serialize(tlv, &tmp, &tmp_len); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } *raw = tmp; tmp = NULL; *raw_len = tmp_len; res = KSI_OK; cleanup: KSI_free(tmp); KSI_TLV_free(tlv); return res; }
int KSI_TlvTemplate_deepCopy(KSI_CTX *ctx, const void *from, const KSI_TlvTemplate *baseTemplate, void *to) { int res = KSI_UNKNOWN_ERROR; KSI_TLV *tmpTlv = NULL; KSI_ERR_clearErrors(ctx); if (ctx == NULL || from == NULL || baseTemplate == NULL || to == NULL) { KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } /* Create a dummy TLV */ res = KSI_TLV_new(ctx, KSI_TLV_PAYLOAD_TLV, 0x0, 0, 0, &tmpTlv); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } /* Create a TLV object */ res = KSI_TlvTemplate_construct(ctx, tmpTlv, from, baseTemplate); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } /* Evaluate the cloned object */ res = KSI_TlvTemplate_extract(ctx, to, tmpTlv, baseTemplate); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_OK; cleanup: KSI_TLV_free(tmpTlv); return res; }
int KSI_PublicationsFile_serialize(KSI_CTX *ctx, KSI_PublicationsFile *pubFile, char **raw, size_t *raw_len) { int res; const unsigned char *buf = NULL; size_t buf_len = 0; KSI_TLV *tlv = NULL; unsigned char *tmp = NULL; size_t tmp_len = 0; size_t sig_len = 0; KSI_ERR_clearErrors(ctx); if (ctx == NULL || pubFile == 0 || raw == NULL || raw_len == NULL) { KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } /** * Create TLV 0x700 that contains nested list of publication file TLVs. * Calculate signed data length assuming that signature TLV is always the last. */ res = KSI_TLV_new(ctx, 0x700, 0, 0, &tlv); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_TlvTemplate_construct(ctx, tlv, pubFile, KSI_TLV_TEMPLATE(KSI_PublicationsFile)); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } res = publicationsFileTLV_getSignatureTLVLength(tlv, &sig_len); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_TLV_getRawValue(tlv, &buf, &buf_len); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } /** * Append raw value to publication file header. Copy raw publication file into * internal and external buffer. */ tmp_len = buf_len + sizeof(PUB_FILE_HEADER_ID) - 1; tmp = (unsigned char *) KSI_malloc(tmp_len); if (tmp == NULL) { KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL); goto cleanup; } if (KSI_strncpy((char *)tmp, PUB_FILE_HEADER_ID, tmp_len) == NULL) { KSI_pushError(ctx, res = KSI_UNKNOWN_ERROR, NULL); goto cleanup; } memcpy(tmp + sizeof(PUB_FILE_HEADER_ID) - 1, buf, buf_len); if (pubFile->raw != NULL) KSI_free(pubFile->raw); pubFile->raw = tmp; pubFile->raw_len = tmp_len; pubFile->signedDataLength = tmp_len - sig_len; tmp = NULL; tmp = (unsigned char *) KSI_malloc(pubFile->raw_len); if (tmp == NULL) { KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL); goto cleanup; } memcpy(tmp, pubFile->raw, pubFile->raw_len); *raw = (char *)tmp; *raw_len = pubFile->raw_len; tmp = NULL; res = KSI_OK; cleanup: KSI_TLV_free(tlv); KSI_free(tmp); return res; }
KSI_END_TLV_TEMPLATE static int replaceCalendarChain(KSI_Signature *sig, KSI_CalendarHashChain *calendarHashChain) { int res; KSI_DataHash *aggrOutputHash = NULL; KSI_TLV *oldCalChainTlv = NULL; KSI_TLV *newCalChainTlv = NULL; KSI_LIST(KSI_TLV) *nestedList = NULL; size_t i; if (sig == NULL || calendarHashChain == NULL) { res = KSI_INVALID_ARGUMENT; goto cleanup; } KSI_ERR_clearErrors(sig->ctx); res = KSI_TLV_getNestedList(sig->baseTlv, &nestedList); if (res != KSI_OK) { KSI_pushError(sig->ctx, res, NULL); goto cleanup; } if (sig->calendarChain != NULL) { for (i = 0; i < KSI_TLVList_length(nestedList); i++) { res = KSI_TLVList_elementAt(nestedList,i, &oldCalChainTlv); if (res != KSI_OK) { KSI_pushError(sig->ctx, res, NULL); goto cleanup; } if (oldCalChainTlv == NULL) { KSI_pushError(sig->ctx, res = KSI_INVALID_SIGNATURE, "Signature TLV element missing."); goto cleanup; } if (KSI_TLV_getTag(oldCalChainTlv) == 0x0802) break; } } res = KSI_TLV_new(sig->ctx, 0x0802, 0, 0, &newCalChainTlv); if (res != KSI_OK) { KSI_pushError(sig->ctx, res, NULL); goto cleanup; } res = KSI_TlvTemplate_construct(sig->ctx, newCalChainTlv, calendarHashChain, KSI_TLV_TEMPLATE(KSI_CalendarHashChain)); if (res != KSI_OK) { KSI_pushError(sig->ctx, res, NULL); goto cleanup; } res = (sig->calendarChain == NULL) ? /* In case there is no calendar hash chain attached, append a new one. */ KSI_TLV_appendNestedTlv(sig->baseTlv, newCalChainTlv) : /* Otherwise replace the calendar hash chain. */ KSI_TLV_replaceNestedTlv(sig->baseTlv, oldCalChainTlv, newCalChainTlv); if (res != KSI_OK) { KSI_pushError(sig->ctx, res, NULL); goto cleanup; } newCalChainTlv = NULL; /* The memory was freed within KSI_TLV_replaceNestedTlv. */ oldCalChainTlv = NULL; KSI_CalendarHashChain_free(sig->calendarChain); sig->calendarChain = calendarHashChain; res = KSI_OK; cleanup: KSI_nofree(nestedList); KSI_DataHash_free(aggrOutputHash); KSI_TLV_free(newCalChainTlv); return res; }