static void testGetLatestPublicationOfLast(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_PublicationRecord *pubRec = NULL;
	KSI_Integer *tm = NULL;
	KSI_PublicationData *pubDat = NULL;
	KSI_Integer *pubTm = NULL;

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	res = KSI_Integer_new(ctx, 1405382400, &tm);
	CuAssert(tc, "Unable to create integer", res == KSI_OK && tm != NULL);

	res = KSI_PublicationsFile_getLatestPublication(pubFile, tm, &pubRec);
	CuAssert(tc, "Unable to find nearest publication", res == KSI_OK && pubRec != NULL);

	res = KSI_PublicationRecord_getPublishedData(pubRec, &pubDat);
	CuAssert(tc, "Unable to get published data", res == KSI_OK && pubDat != NULL);

	res = KSI_PublicationData_getTime(pubDat, &pubTm);
	CuAssert(tc, "Unable to get publication time", res == KSI_OK && pubTm != NULL);

	CuAssert(tc, "Unexpected publication time (this test might fail, if you have recently updated the publications file in the tests)", KSI_Integer_equalsUInt(pubTm, 1405382400));

	KSI_PublicationsFile_free(pubFile);
	KSI_Integer_free(tm);
}
static void testVerifyPublicationsFile(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_PKITruststore *pki = NULL;

	KSI_ERR_clearErrors(ctx);

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	res = KSI_PKITruststore_new(ctx, 0, &pki);
	CuAssert(tc, "Unable to get PKI truststore from context.", res == KSI_OK && pki != NULL);

	res = KSI_CTX_setPKITruststore(ctx, pki);
	CuAssert(tc, "Unable to set new pki truststrore for ksi context.", res == KSI_OK);

	/* Verification should fail. */
	res = KSI_PublicationsFile_verify(pubFile, ctx);
	CuAssert(tc, "Publications file shouldn't verify without mock certificate.", res != KSI_OK);

	/* Verification should succeed. */

	res = KSI_PKITruststore_addLookupFile(pki, getFullResourcePath("resource/tlv/mock.crt"));
	CuAssert(tc, "Unable to read certificate", res == KSI_OK);

	res = KSI_PublicationsFile_verify(pubFile, ctx);

	CuAssert(tc, "Publications file should verify with mock certificate.", res == KSI_OK);

	KSI_PublicationsFile_free(pubFile);
}
static void testLoadPublicationsFileWithNoCerts(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_LIST(KSI_CertificateRecord) *certList = NULL;
	KSI_PKICertificate *cert = NULL;

	unsigned char dummy[] = {0xca, 0xfe, 0xba, 0xbe};
	KSI_OctetString *certId = NULL;

	KSI_ERR_clearErrors(ctx);

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath("resource/publications/publications-nocerts.bin"), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	res = KSI_PublicationsFile_getCertificates(pubFile, &certList);
	CuAssert(tc, "Unable to get certificate list", res == KSI_OK);
	CuAssert(tc, "Unexpected certificate list length.", KSI_CertificateRecordList_length(certList) == 0);

	res = KSI_OctetString_new(ctx, dummy, sizeof(dummy), &certId);
	CuAssert(tc, "Creating an octetstring failed", res == KSI_OK && certId != NULL);

	res = KSI_PublicationsFile_getPKICertificateById(pubFile, certId, &cert);
	CuAssert(tc, "Searching for a non existend certificate failed", res == KSI_OK && cert == NULL);

	KSI_OctetString_free(certId);
	KSI_PublicationsFile_free(pubFile);
}
static void testGetNearestPublicationWithPubTime(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_PublicationRecord *pubRec = NULL;
	KSI_Integer *tm = NULL;
	KSI_PublicationData *pubDat = NULL;
	KSI_Integer *pubTm = NULL;

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	/* With time set to 0, the result should be the first publication record in the publications file. */
	res = KSI_Integer_new(ctx, 1208217600, &tm);
	CuAssert(tc, "Unable to create integer", res == KSI_OK && tm != NULL);

	res = KSI_PublicationsFile_getNearestPublication(pubFile, tm, &pubRec);
	CuAssert(tc, "Unable to find nearest publication", res == KSI_OK && pubRec != NULL);

	res = KSI_PublicationRecord_getPublishedData(pubRec, &pubDat);
	CuAssert(tc, "Unable to get published data", res == KSI_OK && pubDat != NULL);

	res = KSI_PublicationData_getTime(pubDat, &pubTm);
	CuAssert(tc, "Unable to get publication time", res == KSI_OK && pubTm != NULL);

	CuAssert(tc, "Unexpected publication time", KSI_Integer_equalsUInt(pubTm, 1208217600));

	KSI_PublicationRecord_free(pubRec);
	KSI_PublicationsFile_free(pubFile);
	KSI_Integer_free(tm);
}
static void testVerifyPublicationsFileWithAttributeNotPresent(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_CertConstraint arr[] = {
			{NULL, NULL},
			{NULL, NULL}
	};

	KSI_ERR_clearErrors(ctx);


	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	arr[0].oid = "2.5.4.9";
	arr[0].val = "Local pub";
	res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, arr);
	CuAssert(tc, "Unable to delete OID 2.5.4.9", res == KSI_OK);

	/* Verification should fail. */
	res = KSI_PublicationsFile_verify(pubFile, ctx);
	CuAssert(tc, "Publications file must verify with address.", res != KSI_OK);

	arr[0].oid = KSI_CERT_EMAIL;
	arr[0].val = "*****@*****.**";
	res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, arr);
	CuAssert(tc, "Unable to set OID 2.5.4.9 back to normal", res == KSI_OK);

	/* Verification should not fail. */
	res = KSI_PublicationsFile_verify(pubFile, ctx);
	CuAssert(tc, "Publications file must verify.", res == KSI_OK);

	KSI_PublicationsFile_free(pubFile);
}
static void testVerifyPublicationsFileWithNoConstraints(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_CertConstraint arr[] = {
			{NULL, NULL},
			{NULL, NULL}
	};

	KSI_ERR_clearErrors(ctx);


	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, arr);
	CuAssert(tc, "Unable to delete OID 1.2.840.113549.1.9.1", res == KSI_OK);

	/* Verification should not fail. */
	res = KSI_PublicationsFile_verify(pubFile, ctx);
	CuAssert(tc, "Publications file may not verify with no constraints.", res == KSI_PUBFILE_VERIFICATION_NOT_CONFIGURED);

	arr[0].oid = KSI_CERT_EMAIL;
	arr[0].val = "*****@*****.**";
	res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, arr);
	CuAssert(tc, "Unable to set OID 1.2.840.113549.1.9.1 back to normal", res == KSI_OK);

	/* Verification should not fail. */
	res = KSI_PublicationsFile_verify(pubFile, ctx);
	CuAssert(tc, "Publications file must verify with e-mail.", res == KSI_OK);

	KSI_PublicationsFile_free(pubFile);
}
static void testSerializePublicationsFile(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	char *raw = NULL;
	unsigned raw_len = 0;
	FILE *f = NULL;
	int symbol = 0;
	unsigned i= 0;
	
	KSI_ERR_clearErrors(ctx);

	setFileMockResponse(tc, getFullResourcePath(TEST_PUBLICATIONS_FILE));

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	res = KSI_PublicationsFile_serialize(ctx, pubFile, &raw, &raw_len);
	CuAssert(tc, "Unable to serialize publications file", res == KSI_OK && raw != NULL && raw_len != 0);
	
	f = fopen(getFullResourcePath(TEST_PUBLICATIONS_FILE), "rb");
	CuAssert(tc, "Unable to open publications file", res == KSI_OK && f != NULL);
	
	while ((symbol = getc(f)) != EOF && i<raw_len){
		CuAssert(tc, "Serialized publications file mismatch", (char)symbol == raw[i]);
		i++;
	}
	
	CuAssert(tc, "Serialized publications file length  mismatch", i == raw_len);
	
	KSI_PublicationsFile_free(pubFile);
	KSI_free(raw);
	if (f) fclose(f);
}
static void testVerifyPublicationsFileAdditionalPublications(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;

	KSI_ERR_clearErrors(ctx);

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TAMPERED_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "This publications file does not follow the correct format.", res != KSI_OK && pubFile == NULL);

	KSI_PublicationsFile_free(pubFile);
}
static void testLoadPublicationsFile(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;

	KSI_ERR_clearErrors(ctx);

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	KSI_PublicationsFile_free(pubFile);
}
static void testVerifyPublicationsFileWithOrganization(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_CertConstraint arr[] = {
			{KSI_CERT_EMAIL, "*****@*****.**"},
			{NULL, NULL},
			{NULL, NULL}
	};

	KSI_ERR_clearErrors(ctx);


	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	arr[1].oid = KSI_CERT_ORGANIZATION;
	arr[1].val = "Guardtime AS";
	res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, arr);
	CuAssert(tc, "Unable to set OID 2.5.4.10", res == KSI_OK);

	/* Verification should fail. */
	res = KSI_PublicationsFile_verify(pubFile, ctx);
	CuAssert(tc, "Publications file must verify with OID='2.5.4.10' value 'Guardtime AS'.", res == KSI_OK);

	arr[1].val = "Guardtime US";
	res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, arr);
	CuAssert(tc, "Unable to set OID 2.5.4.10", res == KSI_OK);

	/* Verification should fail. */
	res = KSI_PublicationsFile_verify(pubFile, ctx);
	CuAssert(tc, "Publications file may not verify with wrong company'.", res != KSI_OK);
	/* Verification should succeed. */

	arr[1].oid = NULL;
	arr[1].val = NULL;
	res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, arr);
	CuAssert(tc, "Unable to set OID 2.5.4.10", res == KSI_OK);

	/* Verification should fail. */
	res = KSI_PublicationsFile_verify(pubFile, ctx);
	CuAssert(tc, "Publications file must verify with OID='2.5.4.10' removed from the constraints", res == KSI_OK);

	CuAssert(tc, "Publications file should verify with mock certificate.", res == KSI_OK);

	KSI_PublicationsFile_free(pubFile);
}
static void testGetLatestPublicationOfFuture(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_PublicationRecord *pubRec = NULL;
	KSI_Integer *tm = NULL;

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	res = KSI_Integer_new(ctx, 2405382400, &tm);
	CuAssert(tc, "Unable to create integer", res == KSI_OK && tm != NULL);

	res = KSI_PublicationsFile_getLatestPublication(pubFile, tm, &pubRec);
	CuAssert(tc, "This publication should not exist.", res == KSI_OK && pubRec == NULL);

	KSI_PublicationsFile_free(pubFile);
	KSI_Integer_free(tm);
}
static void testGetNearestPublicationOfFuture(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_PublicationRecord *pubRec = NULL;
	KSI_Integer *tm = NULL;

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	/* With time set to 0, the result should be the first publication record in the publications file. */
	res = KSI_Integer_new(ctx, 2208217600, &tm);
	CuAssert(tc, "Unable to create integer", res == KSI_OK && tm != NULL);

	res = KSI_PublicationsFile_getNearestPublication(pubFile, tm, &pubRec);
	CuAssert(tc, "There should not be a valid publication", res == KSI_OK && pubRec == NULL);

	KSI_PublicationRecord_free(pubRec);
	KSI_PublicationsFile_free(pubFile);
	KSI_Integer_free(tm);
}
static void testVerifyPublicationsFileWithFileSpecificConstraints(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_CertConstraint empty[] = {
			{NULL, NULL},
			{NULL, NULL}
	};
	KSI_CertConstraint email[] = {
			{KSI_CERT_EMAIL, "*****@*****.**"},
			{NULL, NULL}
	};

	KSI_CertConstraint wrong[] = {
			{KSI_CERT_EMAIL, "*****@*****.**"},
			{NULL, NULL}
	};

	KSI_CertConstraint unknown[] = {
			{"3.2.840.113549.1.9.1", "*****@*****.**"},
			{NULL, NULL}
	};

	res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, email);
	CuAssert(tc, "Unable to set default certificate constraints", res == KSI_OK);

	res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile);
	CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL);

	res = KSI_PublicationsFile_setCertConstraints(pubFile, NULL);
	CuAssert(tc, "Unable to set publications file certificate constraints.", res == KSI_OK);

	res = KSI_verifyPublicationsFile(ctx, pubFile);
	CuAssert(tc, "Unable to verify publications file with context based constraints.", res == KSI_OK);

	res = KSI_PublicationsFile_setCertConstraints(pubFile, empty);
	CuAssert(tc, "Unable to set publications file certificate constraints.", res == KSI_OK);

	res = KSI_verifyPublicationsFile(ctx, pubFile);
	CuAssert(tc, "Publications file should not verify with empty certificate constraints.", res != KSI_OK);

	res = KSI_PublicationsFile_setCertConstraints(pubFile, email);
	CuAssert(tc, "Unable to set publications file certificate constraints.", res == KSI_OK);

	res = KSI_verifyPublicationsFile(ctx, pubFile);
	CuAssert(tc, "Unable to verify publications file with email.", res == KSI_OK);

	res = KSI_PublicationsFile_setCertConstraints(pubFile, wrong);
	CuAssert(tc, "Unable to set publications file certificate constraints.", res == KSI_OK);

	res = KSI_verifyPublicationsFile(ctx, pubFile);
	CuAssert(tc, "Publications file should not verify with wrong certificate constraints.", res != KSI_OK);

	res = KSI_PublicationsFile_setCertConstraints(pubFile, unknown);
	CuAssert(tc, "Unable to set publications file certificate constraints.", res == KSI_OK);

	res = KSI_verifyPublicationsFile(ctx, pubFile);
	CuAssert(tc, "Publications file should not verify with unknown certificate constraints.", res == KSI_INVALID_ARGUMENT);

	res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, wrong);
	CuAssert(tc, "Unable to set default certificate constraints", res == KSI_OK);

	res = KSI_PublicationsFile_setCertConstraints(pubFile, email);
	CuAssert(tc, "Unable to set publications file certificate constraints.", res == KSI_OK);

	res = KSI_verifyPublicationsFile(ctx, pubFile);
	CuAssert(tc, "Unable to verify publications file with email.", res == KSI_OK);

	KSI_PublicationsFile_free(pubFile);
}