int KSI_Integer_fromTlv(KSI_TLV *tlv, KSI_Integer **o) { int res = KSI_UNKNOWN_ERROR; KSI_CTX *ctx = NULL; KSI_Integer *tmp = NULL; const unsigned char *raw = NULL; size_t len; size_t i; KSI_uint64_t val = 0; ctx = KSI_TLV_getCtx(tlv); KSI_ERR_clearErrors(ctx); if (tlv == NULL || o == NULL) { KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } res = KSI_TLV_getRawValue(tlv, &raw, &len); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } if (len > 8) { KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Integer larger than 64bit"); goto cleanup; } /* Encode the up-to 64bit unsigned integer. */ for (i = 0; i < len; i++) { val = val << 8 | raw[i]; } /* Make sure the integer was coded properly. */ if (len != KSI_UINT64_MINSIZE(val)) { KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Integer not properly formated."); goto cleanup; } res = KSI_Integer_new(ctx, val, &tmp); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } *o = tmp; tmp = NULL; res = KSI_OK; cleanup: KSI_nofree(ctx); KSI_Integer_free(tmp); return res; }
static int publicationsFileTLV_getSignatureTLVLength(KSI_TLV *pubFileTlv, size_t *len) { int res; KSI_TLVList *list = NULL; KSI_TLV *tlvSig = NULL; const unsigned char *raw = NULL; size_t raw_len; size_t sig_len; KSI_CTX *ctx = NULL; if (pubFileTlv == NULL && len == NULL) { KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } ctx = KSI_TLV_getCtx(pubFileTlv); KSI_ERR_clearErrors(ctx); res = KSI_TLV_getNestedList(pubFileTlv, &list); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_TLVList_elementAt(list, KSI_TLVList_length(list) - 1, &tlvSig); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } if (KSI_TLV_getTag(tlvSig) != 0x704) { KSI_pushError(ctx, res, "Last TLV in publications file must be signature (0x704)"); goto cleanup; } res = KSI_TLV_getRawValue(tlvSig, &raw, &raw_len); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } sig_len = raw_len; sig_len += 4; *len = sig_len; cleanup: return res; }
int KSI_PKISignature_fromTlv(KSI_TLV *tlv, KSI_PKISignature **sig) { KSI_CTX *ctx = NULL; int res = KSI_UNKNOWN_ERROR; KSI_PKISignature *tmp = NULL; const unsigned char *raw = NULL; unsigned int raw_len = 0; if (tlv == NULL || sig == NULL){ res = KSI_INVALID_ARGUMENT; goto cleanup; } ctx = KSI_TLV_getCtx(tlv); KSI_ERR_clearErrors(ctx); res = KSI_TLV_getRawValue(tlv, &raw, &raw_len); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_PKISignature_new(ctx, raw, raw_len, &tmp); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } *sig = tmp; tmp = NULL; res = KSI_OK; cleanup: KSI_nofree(raw); KSI_PKISignature_free(tmp); return res; }
int KSI_Utf8String_fromTlv(KSI_TLV *tlv, KSI_Utf8String **o) { int res = KSI_UNKNOWN_ERROR; KSI_CTX *ctx = NULL; const char *cstr = NULL; KSI_Utf8String *tmp = NULL; size_t len; ctx = KSI_TLV_getCtx(tlv); KSI_ERR_clearErrors(ctx); if (tlv == NULL || o == NULL) { KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } res = KSI_TLV_getRawValue(tlv, (const unsigned char **)&cstr, &len); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_Utf8String_new(ctx, cstr, len, &tmp); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } *o = tmp; tmp = NULL; res = KSI_OK; cleanup: KSI_nofree(ctx); KSI_nofree(cstr); KSI_Utf8String_free(tmp); return res; }
int KSI_DataHash_fromTlv(KSI_TLV *tlv, KSI_DataHash **hsh) { int res = KSI_UNKNOWN_ERROR; KSI_CTX *ctx = NULL; const unsigned char *raw = NULL; size_t raw_len = 0; KSI_DataHash *tmp = NULL; ctx = KSI_TLV_getCtx(tlv); KSI_ERR_clearErrors(ctx); if (tlv == NULL || hsh == NULL) { res = KSI_INVALID_ARGUMENT; goto cleanup; } res = KSI_TLV_getRawValue(tlv, &raw, &raw_len); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_DataHash_fromImprint(ctx, raw, raw_len, &tmp); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } *hsh = tmp; tmp = NULL; res = KSI_OK; cleanup: KSI_nofree(ctx); KSI_nofree(raw); KSI_DataHash_free(tmp); 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; }