Example #1
0
static void testMaskingWithMetaDataMultiSig(CuTest *tc) {
#define TEST_AGGR_RESPONSE_FILE  "resource/tlv/test_meta_data_masking.tlv"
	static const unsigned char diceRolls[] = {0xd5, 0x58, 0xaf, 0xfa, 0x80, 0x67, 0xf4, 0x2c, 0xd9, 0x48, 0x36, 0x21, 0xd1, 0xab,
			0xae, 0x23, 0xed, 0xd6, 0xca, 0x04, 0x72, 0x7e, 0xcf, 0xc7, 0xdb, 0xc7, 0x6b, 0xde, 0x34, 0x77, 0x1e, 0x53};
	int res = KSI_UNKNOWN_ERROR;
	KSI_BlockSigner *bs = NULL;
	KSI_MultiSignature *ms = NULL;
	size_t i;
	KSI_DataHash *hsh = NULL;
	KSI_Signature *sig = NULL;
	KSI_DataHash *zero = NULL;
	KSI_OctetString *iv = NULL;

	/* Create zero hash. */
	res = KSI_DataHash_createZero(ctx, KSI_HASHALG_SHA2_512, &zero);
	CuAssert(tc, "Unable to create zero hash.", res == KSI_OK && zero != NULL);

	/* Create random initial vector. */
	res = KSI_OctetString_new(ctx, diceRolls, sizeof(diceRolls), &iv);
	CuAssert(tc, "Unable to create initial vector.", res == KSI_OK && iv != NULL);

	res = KSI_BlockSigner_new(ctx, KSI_HASHALG_SHA1, zero, iv, &bs);
	CuAssert(tc, "Unable to create block signer instance with masking.", res == KSI_OK && bs != NULL);

	addInput(tc, bs, 1);

	res = KSI_CTX_setAggregator(ctx, getFullResourcePathUri(TEST_AGGR_RESPONSE_FILE), TEST_USER, TEST_PASS);
	CuAssert(tc, "Unable to set aggregator file URI.", res == KSI_OK);

	res = KSI_BlockSigner_close(bs, &ms);
	CuAssert(tc, "Unable to close block signer and extract multi signature.", res == KSI_OK && ms != NULL);
	res = KSITest_setDefaultPubfileAndVerInfo(ctx);
	CuAssert(tc, "Unable to set default pubfile, default cert and default pki constraints.", res == KSI_OK);

	/* Lets loop over all the inputs and try to verify them. */
	for (i = 0; input_data[i] != NULL; i++) {
		res = KSI_DataHash_create(ctx, input_data[i], strlen(input_data[i]), KSI_HASHALG_SHA2_256, &hsh);
		CuAssert(tc, "Unable to create data hash.", res == KSI_OK && hsh != NULL);

		res = KSI_MultiSignature_get(ms, hsh, &sig);
		CuAssert(tc, "Unable to extract signature from the multi signature container.", res == KSI_OK && sig != NULL);

		res = KSI_Signature_verifyDocument(sig, ctx, (void *)input_data[i], strlen(input_data[i]));
		CuAssert(tc, "Unable to verify the input data.", res == KSI_OK);
		KSI_Signature_free(sig);
		sig = NULL;

		KSI_DataHash_free(hsh);
		hsh = NULL;
	}

	KSI_OctetString_free(iv);
	KSI_DataHash_free(zero);
	KSI_DataHash_free(hsh);
	KSI_MultiSignature_free(ms);
	KSI_BlockSigner_free(bs);
#undef TEST_AGGR_RESPONSE_FILE
}
Example #2
0
static void testVerifyDocumentHash(CuTest *tc) {
	int res;

	unsigned char in[0x1ffff];
	unsigned in_len = 0;

	char doc[] = "LAPTOP";
	KSI_DataHash *hsh = NULL;

	FILE *f = NULL;
	KSI_Signature *sig = NULL;

	KSI_ERR_clearErrors(ctx);

	f = fopen(getFullResourcePath(TEST_SIGNATURE_FILE), "rb");
	CuAssert(tc, "Unable to open signature file.", f != NULL);

	in_len = (unsigned)fread(in, 1, sizeof(in), f);
	CuAssert(tc, "Nothing read from signature file.", in_len > 0);

	fclose(f);

	res = KSI_Signature_parse(ctx, in, in_len, &sig);
	CuAssert(tc, "Failed to parse signature", res == KSI_OK && sig != NULL);

	/* Chech correct document. */
	res = KSI_DataHash_create(ctx, doc, strlen(doc), KSI_HASHALG_SHA2_256, &hsh);
	CuAssert(tc, "Failed to create data hash", res == KSI_OK && hsh != NULL);

	res = KSI_Signature_verifyDataHash(sig, ctx, hsh);
	CuAssert(tc, "Failed to verify valid document", res == KSI_OK);

	KSI_DataHash_free(hsh);
	hsh = NULL;

	/* Chech wrong document. */
	res = KSI_DataHash_create(ctx, doc, sizeof(doc), KSI_HASHALG_SHA2_256, &hsh);
	CuAssert(tc, "Failed to create data hash", res == KSI_OK && hsh != NULL);

	res = KSI_Signature_verifyDataHash(sig, ctx, hsh);
	CuAssert(tc, "Verification did not fail with expected error.", res == KSI_VERIFICATION_FAILURE);

	KSI_DataHash_free(hsh);
	hsh = NULL;

	/* Check correct document with wrong hash algorithm. */
	res = KSI_DataHash_create(ctx, doc, strlen(doc), KSI_HASHALG_SHA2_512, &hsh);
	CuAssert(tc, "Failed to create data hash", res == KSI_OK && hsh != NULL);

	res = KSI_Signature_verifyDataHash(sig, ctx, hsh);
	CuAssert(tc, "Verification did not fail with expected error.", res == KSI_VERIFICATION_FAILURE);

	KSI_DataHash_free(hsh);


	KSI_Signature_free(sig);
}
Example #3
0
static void testExtend(CuTest *tc) {
	int res;
	KSI_MultiSignature *ms = NULL;
	KSI_DataHash *hsh = NULL;
	KSI_Signature *sig = NULL;
	KSI_PublicationRecord *pubRec = NULL;

	res = KSI_MultiSignature_fromFile(ctx, getFullResourcePath("resource/multi_sig/test2.mksi"), &ms);
	CuAssert(tc, "Unable to read multi signature container from file.", res == KSI_OK && ms != NULL);

	res = KSI_CTX_setExtender(ctx, getFullResourcePathUri("resource/multi_sig/test2-extend_response-multiple.tlv"), "anon", "anon");
	CuAssert(tc, "Unable to set extender response from file", res == KSI_OK);

	res = KSI_MultiSignature_extend(ms);
	CuAssert(tc, "Unable to perform multi signature container extension.", res == KSI_OK);

	KSITest_DataHash_fromStr(ctx, "0111a700b0c8066c47ecba05ed37bc14dcadb238552d86c659342d1d7e87b8772d", &hsh);

	res = KSI_MultiSignature_get(ms, hsh, &sig);
	CuAssert(tc, "Unable to get signature from container.", res == KSI_OK && sig != NULL);

	res = KSI_verifySignature(ctx, sig);
	CuAssert(tc, "Unable to verify signature extracted from container.", res == KSI_OK);

	res = KSI_Signature_getPublicationRecord(sig, &pubRec);
	CuAssert(tc, "Signature should be extended.", res == KSI_OK && pubRec != NULL);

	KSI_Signature_free(sig);
	KSI_DataHash_free(hsh);
	KSI_MultiSignature_free(ms);
}
Example #4
0
static void testGetOldest(CuTest *tc) {
	int res;
	KSI_MultiSignature *ms = NULL;
	KSI_DataHash *hsh = NULL;
	KSI_Signature *sig = NULL;
	KSI_Integer *tm = NULL;

	res = KSI_MultiSignature_fromFile(ctx, getFullResourcePath("resource/multi_sig/test2.mksi"), &ms);
	CuAssert(tc, "Unable to read multi signature container from file.", res == KSI_OK && ms != NULL);

	KSITest_DataHash_fromStr(ctx, "0111a700b0c8066c47ecba05ed37bc14dcadb238552d86c659342d1d7e87b8772d", &hsh);

	res = KSI_MultiSignature_get(ms, hsh, &sig);
	CuAssert(tc, "Unable to get signature from container.", res == KSI_OK && sig != NULL);

	res = KSI_verifySignature(ctx, sig);
	CuAssert(tc, "Unable to verify signature extracted from container.", res == KSI_OK);

	res = KSI_Signature_getSigningTime(sig, &tm);
	CuAssert(tc, "Wrong signing time (probably returning the newer signature).", res == KSI_OK && KSI_Integer_equalsUInt(tm, 1398866256));

	KSI_Signature_free(sig);
	KSI_DataHash_free(hsh);
	KSI_MultiSignature_free(ms);
}
Example #5
0
static void addInput(CuTest *tc, KSI_BlockSigner *bs, int genMeta) {
	int res = KSI_UNKNOWN_ERROR;
	size_t i;
	KSI_DataHash *hsh = NULL;
	KSI_MetaData *md = NULL;

	for (i = 0; input_data[i] != NULL; i++) {
		res = KSI_DataHash_create(ctx, input_data[i], strlen(input_data[i]), KSI_HASHALG_SHA2_256, &hsh);
		CuAssert(tc, "Unable to create data hash.", res == KSI_OK && hsh != NULL);

		if (genMeta) {
			char clientId[100];
			KSI_snprintf(clientId, sizeof(clientId), "Client-%d", i);

			res = createMetaData(clientId, &md);
			CuAssert(tc, "Unable to create metadata.", res == KSI_OK && md != NULL);

			res = KSI_BlockSigner_addLeaf(bs, hsh, 0, md, NULL);
			CuAssert(tc, "Unable to add leaf with meta data.", res == KSI_OK);

			KSI_MetaData_free(md);
			md = NULL;
		} else {
			res = KSI_BlockSigner_add(bs, hsh);
			CuAssert(tc, "Unable to add data hash to the block signer.", res == KSI_OK);
		}
		KSI_DataHash_free(hsh);
		hsh = NULL;
	}
}
Example #6
0
static void testDeleteSignatureAppendedFromFile(CuTest *tc, const char *fname) {
	int res;
	KSI_MultiSignature *ms = NULL;
	KSI_Signature *sig = NULL;
	KSI_HashAlgorithm *arr = NULL;
	KSI_DataHash *hsh = NULL;

	res = KSI_MultiSignature_new(ctx, &ms);
	CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL);

	res = KSI_Signature_fromFile(ctx, fname, &sig);
	CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL);

	res = KSI_Signature_getDocumentHash(sig, &hsh);
	CuAssert(tc, "Unable to retrieve signed document hash from the signature.", res == KSI_OK && hsh != NULL);
	KSI_DataHash_ref(hsh);

	res = KSI_MultiSignature_add(ms, sig);
	CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK);

	KSI_Signature_free(sig);
	sig = NULL;

	res = KSI_MultiSignature_remove(ms, hsh);
	CuAssert(tc, "Unable to remove signature.", res == KSI_OK);

	res = KSI_MultiSignature_get(ms, hsh, &sig);
	CuAssert(tc, "There should not be a signature with this hash value anymore.", res == KSI_MULTISIG_NOT_FOUND && sig == NULL);
	/* TimeMapper list functions are not exported so we need to cast to generic list. */
	CuAssert(tc, "The internal structure should be empty", KSI_List_length((KSI_List *)ms->timeList) == 0);

	KSI_MultiSignature_free(ms);
	KSI_DataHash_free(hsh);
	KSI_free(arr);
}
Example #7
0
int KSI_DataHash_createZero(KSI_CTX *ctx, KSI_HashAlgorithm algo_id, KSI_DataHash **hsh) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_DataHash *tmp = NULL;
	unsigned char buf[KSI_MAX_IMPRINT_LEN];

	if (ctx == NULL || hsh == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	memset(buf, 0, sizeof(buf));
	buf[0] = algo_id;

	if (!KSI_isHashAlgorithmSupported(algo_id)) {
		KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, "Hash algorithm not supported.");
		goto cleanup;
	}

	res = KSI_DataHash_fromImprint(ctx, buf, (KSI_hashAlgorithmInfo[algo_id].outputBitCount >> 3) + 1, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	*hsh = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_DataHash_free(tmp);

	return res;
}
Example #8
0
static void testExtractingNotExisting(CuTest* tc) {
	int res;
	KSI_Signature *sig = NULL;
	KSI_MultiSignature *ms = NULL;
	KSI_DataHash *hsh = NULL;


	KSI_ERR_clearErrors(ctx);

	res = KSI_Signature_fromFile(ctx, getFullResourcePath(TEST_SIGNATURE_FILE), &sig);
	CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL);

	res = KSI_MultiSignature_new(ctx, &ms);
	CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL);

	res = KSI_MultiSignature_add(ms, sig);
	CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK);

	KSI_Signature_free(sig);
	sig = NULL;

	KSITest_DataHash_fromStr(ctx, "01db27c0db0aebb8d3963c3a720985cedb600f91854cdb1e45ad631611c39284dd", &hsh);

	res = KSI_MultiSignature_get(ms, hsh, &sig);
	CuAssert(tc, "Get should fail with KSI_MULTISIG_NOT_FOUND", res == KSI_MULTISIG_NOT_FOUND && sig == NULL);

	KSI_DataHash_free(hsh);
	KSI_MultiSignature_free(ms);
	KSI_Signature_free(sig);
}
Example #9
0
static int verifyCalendarChainWithPublication(KSI_Signature *sig){
	int res = KSI_UNKNOWN_ERROR;
	KSI_CalendarHashChain *calChain = NULL;
	KSI_Integer *pubTime = NULL;
	KSI_DataHash *rootHash = NULL;
	KSI_PublicationRecord *sigPubRec = NULL;
	KSI_PublicationData *sigPubData = NULL;
	KSI_DataHash *publishedHash = NULL;
	KSI_Integer *publishedTime = NULL;
	KSI_VerificationStep step = KSI_VERIFY_CALCHAIN_WITH_PUBLICATION;
	KSI_VerificationResult *info = &sig->verificationResult;

	if (sig->publication == NULL) {
		res = KSI_OK;
		goto cleanup;
	}

	KSI_LOG_debug(sig->ctx, "Verifying calendar chain with publication.");

	calChain = sig->calendarChain;
	res = KSI_CalendarHashChain_getPublicationTime(calChain, &pubTime);
	if (res != KSI_OK) goto cleanup;

	res = KSI_CalendarHashChain_aggregate(calChain, &rootHash);
	if (res != KSI_OK) goto cleanup;

	sigPubRec = sig->publication;
	res = KSI_PublicationRecord_getPublishedData(sigPubRec, &sigPubData);
	if (res != KSI_OK) goto cleanup;

	res = KSI_PublicationData_getImprint(sigPubData, &publishedHash);
	if (res != KSI_OK) goto cleanup;

	res = KSI_PublicationData_getTime(sigPubData, &publishedTime);
	if (res != KSI_OK) goto cleanup;


	if (!KSI_DataHash_equals(rootHash, publishedHash)){
		KSI_LOG_logDataHash(sig->ctx, KSI_LOG_DEBUG, "Calendar root hash", rootHash);
		KSI_LOG_logDataHash(sig->ctx, KSI_LOG_DEBUG, "Published hash", publishedHash);
		res = KSI_VerificationResult_addFailure(info, step, "Published hash and calendar hash chain root hash mismatch.");
		goto cleanup;
	}

	if (!KSI_Integer_equals(pubTime, publishedTime)){
		KSI_LOG_debug(sig->ctx, "Calendar hash chain publication time: %i.", KSI_Integer_getUInt64(pubTime));
		KSI_LOG_debug(sig->ctx, "Published publication time: %i.", KSI_Integer_getUInt64(publishedTime));
		res = KSI_VerificationResult_addFailure(info, step, "Calendar hash chain publication time mismatch.");
		goto cleanup;
	}

	res = KSI_VerificationResult_addSuccess(info, step, "Calendar chain verified with publication.");

cleanup:

	KSI_DataHash_free(rootHash);

	return res;
}
Example #10
0
/**
 * KSI_PublicationData
 */
void KSI_PublicationData_free(KSI_PublicationData *t) {
	if (t != NULL && --t->ref == 0) {
		KSI_Integer_free(t->time);
		KSI_DataHash_free(t->imprint);
		KSI_TLV_free(t->baseTlv);
		KSI_free(t);
	}
}
Example #11
0
int GetDocumentHash(char *fileName, KSI_Signature *sig, KSI_DataHash **hsh) {
    int res = KSI_UNKNOWN_ERROR;
    KSI_DataHash *tmp = NULL;
    KSI_DataHasher *hsr = NULL;
    FILE *in = NULL;
    unsigned char buf[1024];
    size_t buf_len;

    if (fileName == NULL || sig == NULL || hsh == NULL) {
        res = KSI_INVALID_ARGUMENT;
        goto cleanup;
    }

    /* Create hasher. */
    res = KSI_Signature_createDataHasher(sig, &hsr);
    if (res != KSI_OK) {
        fprintf(stderr, "Unable to create data hasher.\n");
        goto cleanup;
    }

    /* Open the document for reading. */
    in = fopen(fileName, "rb");
    if (in == NULL) {
        fprintf(stderr, "Unable to open data file '%s'.\n", fileName);
        goto cleanup;
    }

    /* Calculate the hash of the document. */
    while (!feof(in)) {
        buf_len = fread(buf, 1, sizeof(buf), in);
        res = KSI_DataHasher_add(hsr, buf, buf_len);
        if (res != KSI_OK) {
            fprintf(stderr, "Unable hash the document.\n");
            goto cleanup;
        }
    }

    /* Finalize the hash computation. */
    res = KSI_DataHasher_close(hsr, &tmp);
    if (res != KSI_OK) {
        fprintf(stderr, "Failed to close the hashing process.\n");
        goto cleanup;
    }

    *hsh = tmp;
    tmp = NULL;
    res = KSI_OK;

cleanup:

    KSI_DataHasher_free(hsr);
    KSI_DataHash_free(tmp);
    if (in != NULL) fclose(in);

    return res;
}
Example #12
0
static void testMultiSig(CuTest *tc) {
#define TEST_AGGR_RESPONSE_FILE  "resource/tlv/ok-aggr-resp-1460631424.tlv"
	int res = KSI_UNKNOWN_ERROR;
	KSI_BlockSigner *bs = NULL;
	KSI_MultiSignature *ms = NULL;
	size_t i;
	KSI_DataHash *hsh = NULL;
	KSI_Signature *sig = NULL;

	res = KSI_BlockSigner_new(ctx, KSI_HASHALG_SHA1, NULL, NULL, &bs);
	CuAssert(tc, "Unable to create block signer instance.", res == KSI_OK && bs != NULL);

	addInput(tc, bs, 0);

	res = KSI_CTX_setAggregator(ctx, getFullResourcePathUri(TEST_AGGR_RESPONSE_FILE), TEST_USER, TEST_PASS);
	CuAssert(tc, "Unable to set aggregator file URI.", res == KSI_OK);

	res = KSI_BlockSigner_close(bs, &ms);
	CuAssert(tc, "Unable to close block signer and extract multi signature.", res == KSI_OK && ms != NULL);

	/* Lets loop over all the inputs and try to verify them. */
	for (i = 0; input_data[i] != NULL; i++) {
		res = KSI_DataHash_create(ctx, input_data[i], strlen(input_data[i]), KSI_HASHALG_SHA2_256, &hsh);
		CuAssert(tc, "Unable to create data hash.", res == KSI_OK && hsh != NULL);

		res = KSI_MultiSignature_get(ms, hsh, &sig);
		CuAssert(tc, "Unable to extract signature from the multi signature container.", res == KSI_OK && sig != NULL);

		res = KSI_Signature_verifyDocument(sig, ctx, (void *)input_data[i], strlen(input_data[i]));
		CuAssert(tc, "Unable to verify the input data.", res == KSI_OK);

		KSI_Signature_free(sig);
		sig = NULL;

		KSI_DataHash_free(hsh);
		hsh = NULL;
	}

	KSI_DataHash_free(hsh);
	KSI_MultiSignature_free(ms);
	KSI_BlockSigner_free(bs);
#undef TEST_AGGR_RESPONSE_FILE
}
Example #13
0
static void testMaskingInput(CuTest *tc) {
	static const unsigned char diceRolls[] = {0xd5, 0x58, 0xaf, 0xfa, 0x80, 0x67, 0xf4, 0x2c, 0xd9, 0x48, 0x36, 0x21, 0xd1, 0xab,
			0xae, 0x23, 0xed, 0xd6, 0xca, 0x04, 0x72, 0x7e, 0xcf, 0xc7, 0xdb, 0xc7, 0x6b, 0xde, 0x34, 0x77, 0x1e, 0x53};
	int res;
	KSI_BlockSigner *bs = NULL;
	KSI_OctetString *iv = NULL;
	KSI_DataHash *zero = NULL;
	size_t i;

	struct {
		KSI_CTX *ctx;
		KSI_HashAlgorithm algo_id;
		KSI_DataHash *prevHash;
		KSI_OctetString *iv;
		KSI_BlockSigner **bs;
		int expectedRes;
	} tests[] = {
			{NULL, KSI_HASHALG_SHA3_512, NULL, NULL, NULL, KSI_INVALID_ARGUMENT},
			{NULL, KSI_HASHALG_SHA3_512, NULL, NULL, &bs, KSI_INVALID_ARGUMENT},
			{NULL, KSI_HASHALG_SHA3_512, NULL, iv, &bs, KSI_INVALID_ARGUMENT},
			{NULL, KSI_HASHALG_SHA3_512, zero, NULL, &bs, KSI_INVALID_ARGUMENT},
			{ctx, KSI_HASHALG_SHA3_512, NULL, NULL, &bs, KSI_UNAVAILABLE_HASH_ALGORITHM},
			{NULL, KSI_HASHALG_SHA2_512, NULL, NULL, NULL, KSI_INVALID_ARGUMENT},
			{NULL, KSI_HASHALG_SHA2_512, NULL, NULL, &bs, KSI_INVALID_ARGUMENT},
			{NULL, KSI_HASHALG_SHA2_512, NULL, iv, &bs, KSI_INVALID_ARGUMENT},
			{NULL, KSI_HASHALG_SHA2_512, zero, NULL, &bs, KSI_INVALID_ARGUMENT},
			{ctx, KSI_HASHALG_SHA2_512, zero, NULL, &bs, KSI_OK},
			{NULL, -1, NULL, NULL, NULL, -1}
	};

	/* Create zero hash. */
	res = KSI_DataHash_createZero(ctx, KSI_HASHALG_SHA2_512, &zero);
	CuAssert(tc, "Unable to create zero hash.", res == KSI_OK && zero != NULL);

	/* Create random initial vector. */
	res = KSI_OctetString_new(ctx, diceRolls, sizeof(diceRolls), &iv);
	CuAssert(tc, "Unable to create initial vector.", res == KSI_OK && iv != NULL);

	res = KSI_BlockSigner_new(ctx, KSI_HASHALG_SHA1, zero, iv, &bs);
	CuAssert(tc, "Unable to create block signer instance with masking.", res == KSI_OK && bs != NULL);

	for (i = 0; tests[i].expectedRes != -1; i++) {
		res = KSI_BlockSigner_new(tests[i].ctx, tests[i].algo_id, tests[i].prevHash, tests[i].iv, tests[i].bs);
		KSI_BlockSigner_free(bs);
		bs = NULL;
		if (res != tests[i].expectedRes) {
			char buf[1000];
			KSI_snprintf(buf, sizeof(buf), "Unexpected result @%i (expected = '%s', but was '%s').", i, KSI_getErrorString(tests[i].expectedRes), KSI_getErrorString(res));
			CuFail(tc, buf);
		}
	}

	KSI_OctetString_free(iv);
	KSI_DataHash_free(zero);
}
static void testFindPublicationByPubStr(CuTest *tc) {
	static const char publication[] = "AAAAAA-CTJR3I-AANBWU-RY76YF-7TH2M5-KGEZVA-WLLRGD-3GKYBG-AM5WWV-4MCLSP-XPRDDI-UFMHBA";
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_PublicationRecord *pubRec = NULL;
	KSI_PublicationData *pub = NULL;
	KSI_DataHash *pubHsh = NULL;
	KSI_Integer *pubTime = NULL;
	KSI_DataHash *expHsh = NULL;
	unsigned char buf[0xff];
	size_t len;
	KSI_CTX *ctx = NULL;

	res = KSITest_CTX_clone(&ctx);
	CuAssert(tc, "Unable to create KSI context.", res == KSI_OK && ctx != NULL);

	res = KSITest_setDefaultPubfileAndVerInfo(ctx);
	CuAssert(tc, "Unable to set default values to context.", res == KSI_OK);

	KSI_ERR_clearErrors(ctx);

	res = KSI_CTX_setPublicationUrl(ctx, getFullResourcePathUri(TEST_PUBLICATIONS_FILE));
	CuAssert(tc, "Unable to set pubfile URI.", res == KSI_OK);

	res = KSI_receivePublicationsFile(ctx, &pubFile);
	CuAssert(tc, "Unable to get publications file.", res == KSI_OK && pubFile != NULL);

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

	res = KSI_PublicationsFile_getPublicationDataByPublicationString(pubFile, publication, &pubRec);
	CuAssert(tc, "Unable to get publication record by publication string.", res == KSI_OK && pubRec != NULL);

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

	res = KSI_PublicationData_getImprint(pub, &pubHsh);
	CuAssert(tc, "Unable to get published hash", res == KSI_OK && pubHsh != NULL);

	res = KSI_PublicationData_getTime(pub, &pubTime);
	CuAssert(tc, "Unable to get publication time.", res == KSI_OK && pubTime != NULL);

	KSITest_decodeHexStr("01a1b5238ffb05fccfa67546266a0b2d7130f6656026033b6b578c12e4fbbe231a", buf, sizeof(buf), &len);
	res = KSI_DataHash_fromImprint(ctx, buf, len, &expHsh);
	CuAssert(tc, "Unable to get data hash from imprint.", res == KSI_OK && expHsh != NULL);

	CuAssert(tc, "Publication hash mismatch.", KSI_DataHash_equals(expHsh, pubHsh));
	CuAssert(tc, "Publication time mismatch", KSI_Integer_equalsUInt(pubTime, 1397520000));

	KSI_DataHash_free(expHsh);
	KSI_PublicationsFile_free(pubFile);
	KSI_CTX_free(ctx);

}
Example #15
0
static void testReset(CuTest *tc) {
#define TEST_AGGR_RESPONSE_FILE  "resource/tlv/ok-sig-2014-07-01.1-aggr_response.tlv"
	int res = KSI_UNKNOWN_ERROR;
	KSI_BlockSigner *bs = NULL;
	KSI_DataHash *hsh = NULL;
	KSI_BlockSignerHandle *h = NULL;
	KSI_Signature *sig = NULL;
	unsigned char *raw = NULL;
	size_t len = 0;

	res = KSI_CTX_setAggregator(ctx, getFullResourcePathUri(TEST_AGGR_RESPONSE_FILE), TEST_USER, TEST_PASS);
	CuAssert(tc, "Unable to set aggregator file URI.", res == KSI_OK);

	res = KSITest_DataHash_fromStr(ctx, "0111a700b0c8066c47ecba05ed37bc14dcadb238552d86c659342d1d7e87b8772d", &hsh);
	CuAssert(tc, "Unable to create data hash.", res == KSI_OK && hsh != NULL);

	res = KSI_BlockSigner_new(ctx, KSI_HASHALG_SHA1, NULL, NULL, &bs);
	CuAssert(tc, "Unable to create block signer instance.", res == KSI_OK && bs != NULL);

	/* Add the temporary leafs. */

	res = KSI_BlockSigner_addLeaf(bs, hsh, 0, NULL, NULL);
	CuAssert(tc, "Unable to add 1st mock hash to the blocksigner.", res == KSI_OK);

	res = KSI_BlockSigner_addLeaf(bs, hsh, 0, NULL, NULL);
	CuAssert(tc, "Unable to add 2nd hash to the blocksigner.", res == KSI_OK);

	res = KSI_BlockSigner_addLeaf(bs, hsh, 0, NULL, NULL);
	CuAssert(tc, "Unable to add 3rd hash to the blocksigner.", res == KSI_OK);

	res = KSI_BlockSigner_reset(bs);
	CuAssert(tc, "Unable to reset the block signer.", res == KSI_OK);

	res = KSI_BlockSigner_addLeaf(bs, hsh, 0, NULL, &h);
	CuAssert(tc, "Unable to add actual hash to the blocksigner.", res == KSI_OK && h != NULL);

	res = KSI_BlockSigner_close(bs, NULL);
	CuAssert(tc, "Unable to close blocksigner.", res == KSI_OK);

	res = KSI_BlockSignerHandle_getSignature(h, &sig);
	CuAssert(tc, "Unable to extract signature from the blocksigner.", res == KSI_OK && sig != NULL);

	res = KSI_Signature_serialize(sig, &raw, &len);
	CuAssert(tc, "Unable to serialize signature.", res == KSI_OK && raw != NULL && len > 0);

	KSI_LOG_logBlob(ctx, KSI_LOG_DEBUG, "Serialized single signature from block signer.", raw, len);

	KSI_BlockSignerHandle_free(h);
	KSI_Signature_free(sig);
	KSI_BlockSigner_free(bs);
	KSI_DataHash_free(hsh);
	KSI_free(raw);
#undef TEST_AGGR_RESPONSE_FILE
}
Example #16
0
static int verifyCalendarChain(KSI_Signature *sig) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_DataHash *rootHash = NULL;
	KSI_Integer *calendarPubTm = NULL;
	KSI_PublicationData *pubData = NULL;
	KSI_DataHash *pubHash = NULL;
	KSI_Integer *pubTime = NULL;
	KSI_VerificationStep step = KSI_VERIFY_CALCHAIN_WITH_CALAUTHREC;
	KSI_VerificationResult *info = &sig->verificationResult;

	if (sig->calendarAuthRec == NULL) {
		res = KSI_OK;
		goto cleanup;
	}

	KSI_LOG_info(sig->ctx, "Verifying calendar hash chain.");

	/* Calculate the root hash value. */
	res = KSI_CalendarHashChain_aggregate(sig->calendarChain, &rootHash);
	if (res != KSI_OK) goto cleanup;

	/* Get the publication time from calendar hash chain. */
	res = KSI_CalendarHashChain_getPublicationTime(sig->calendarChain, &calendarPubTm);
	if (res != KSI_OK) goto cleanup;

	/* Get publication data. */
	res = KSI_CalendarAuthRec_getPublishedData(sig->calendarAuthRec, &pubData);
	if (res != KSI_OK) goto cleanup;

	/* Get published hash value. */
	res = KSI_PublicationData_getImprint(pubData, &pubHash);
	if (res != KSI_OK) goto cleanup;

	/* Get publication time. */
	res = KSI_PublicationData_getTime(pubData, &pubTime);
	if (res != KSI_OK) goto cleanup;

	if (KSI_Integer_equals(calendarPubTm, pubTime) && KSI_DataHash_equals(rootHash, pubHash)) {
		res = KSI_VerificationResult_addSuccess(info, step, "Calendar chain and authentication record match.");
	} else {
		res = KSI_VerificationResult_addFailure(info, step, "Calendar chain and authentication record mismatch.");
	}

	if (res != KSI_OK) goto cleanup;

	res = KSI_OK;

cleanup:

	KSI_DataHash_free(rootHash);

	return res;
}
Example #17
0
int KSI_DataHash_fromDigest(KSI_CTX *ctx, KSI_HashAlgorithm algo_id, const unsigned char *digest, size_t digest_length, KSI_DataHash **hash) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_DataHash *tmp_hash = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || digest == NULL || digest_length == 0 || hash == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	/* Make sure the algorithm is supported. */
	if (!KSI_isHashAlgorithmSupported(algo_id)) {
		KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, "Hash algorithm not supported.");
		goto cleanup;
	}

	/* Verify the length of the digest with the algorithm. */
	if (KSI_getHashLength(algo_id) != digest_length) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Digest length does not match with algorithm.");
		goto cleanup;
	}

	/* Make sure it fits. */
	if (digest_length > KSI_MAX_IMPRINT_LEN) {
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Internal buffer too short to hold imprint");
		goto cleanup;
	}

	tmp_hash = KSI_new(KSI_DataHash);
	if (tmp_hash == NULL) {
		KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}

	tmp_hash->ref = 1;
	tmp_hash->ctx = ctx;

	tmp_hash->imprint[0] = (unsigned char)algo_id;
	memcpy(tmp_hash->imprint + 1, digest, digest_length);
	tmp_hash->imprint_length = digest_length + 1;

	*hash = tmp_hash;
	tmp_hash = NULL;

	res = KSI_OK;

cleanup:

	KSI_DataHash_free(tmp_hash);

	return res;
}
static void testFindPublicationByTime(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_PublicationRecord *pubRec = NULL;
	KSI_PublicationData *pub = NULL;
	KSI_DataHash *pubHsh = NULL;
	KSI_Integer *pubTime = NULL;
	KSI_DataHash *expHsh = NULL;
	KSI_LIST(KSI_Utf8String) *pubRefList = NULL;
	unsigned char buf[0xff];
	unsigned len;

	KSI_ERR_clearErrors(ctx);

	res = KSI_receivePublicationsFile(ctx, &pubFile);
	CuAssert(tc, "Unable to get publications file.", res == KSI_OK && pubFile != NULL);

	res = KSI_Integer_new(ctx, 1397520000, &pubTime);
	CuAssert(tc, "Unable to create ksi integer object.", res == KSI_OK && pubTime != NULL);

	res = KSI_PublicationsFile_getPublicationDataByTime(pubFile, pubTime, &pubRec);
	CuAssert(tc, "Unable to get publication record by publication date.", res == KSI_OK && pubRec != NULL);

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

	res = KSI_PublicationData_getImprint(pub, &pubHsh);
	CuAssert(tc, "Unable to get published hash", res == KSI_OK && pubHsh != NULL);

	KSI_Integer_free(pubTime);
	pubTime = NULL;

	res = KSI_PublicationData_getTime(pub, &pubTime);
	CuAssert(tc, "Unable to get publication time.", res == KSI_OK && pubTime != NULL);

	KSITest_decodeHexStr("01a1b5238ffb05fccfa67546266a0b2d7130f6656026033b6b578c12e4fbbe231a", buf, sizeof(buf), &len);
	res = KSI_DataHash_fromImprint(ctx, buf, len, &expHsh);
	CuAssert(tc, "Unable to get datahash from imprint", res == KSI_OK && expHsh != NULL);

	CuAssert(tc, "Publication hash mismatch.", KSI_DataHash_equals(expHsh, pubHsh));
	CuAssert(tc, "Publication time mismatch", KSI_Integer_equalsUInt(pubTime, 1397520000));

	res = KSI_PublicationRecord_getPublicationRefList(pubRec, &pubRefList);
	CuAssert(tc, "Unable to get publications ref list", res == KSI_OK && pubRefList != NULL);

	KSI_DataHash_free(expHsh);
}
Example #19
0
int KSI_DataHash_create(KSI_CTX *ctx, const void *data, size_t data_length, KSI_HashAlgorithm algo_id, KSI_DataHash **hash) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_DataHash *hsh = NULL;
	KSI_DataHasher *hsr = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || hash == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	res = KSI_DataHasher_open(ctx, algo_id, &hsr);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	if (data != NULL && data_length > 0) {
		res = KSI_DataHasher_add(hsr, data, data_length);
		if (res != KSI_OK) {
			KSI_pushError(ctx, res, NULL);
			goto cleanup;
		}
	}

	res = KSI_DataHasher_close(hsr, &hsh);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	*hash = hsh;
	hsh = NULL;

	res = KSI_OK;

cleanup:

	KSI_DataHash_free(hsh);
	KSI_DataHasher_free(hsr);

	return res;
}
Example #20
0
static void testParseAndVerifySingle(CuTest *tc) {
	int res;
	KSI_MultiSignature *ms = NULL;
	KSI_DataHash *hsh = NULL;
	KSI_Signature *sig = NULL;

	createMultiSignatureFromFile(tc, getFullResourcePath("resource/multi_sig/test1.mksi"), &ms);

	KSITest_DataHash_fromStr(ctx, "0111a700b0c8066c47ecba05ed37bc14dcadb238552d86c659342d1d7e87b8772d", &hsh);

	res = KSI_MultiSignature_get(ms, hsh, &sig);
	CuAssert(tc, "Unable to get signature from container.", res == KSI_OK && sig != NULL);

	res = KSI_verifySignature(ctx, sig);
	CuAssert(tc, "Unable to verify signature extracted from container.", res == KSI_OK);

	KSI_Signature_free(sig);
	KSI_DataHash_free(hsh);
	KSI_MultiSignature_free(ms);
}
Example #21
0
static void testExtractingFromEmpty(CuTest* tc) {
	int res;
	KSI_Signature *sig = NULL;
	KSI_MultiSignature *ms = NULL;
	KSI_DataHash *hsh = NULL;

	KSI_ERR_clearErrors(ctx);

	KSITest_DataHash_fromStr(ctx, "01db27c0db0aebb8d3963c3a720985cedb600f91854cdb1e45ad631611c39284dd", &hsh);

	res = KSI_MultiSignature_new(ctx, &ms);
	CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL);

	res = KSI_MultiSignature_get(ms, hsh, &sig);
	CuAssert(tc, "Get should fail with KSI_MULTISIG_NOT_FOUND", res == KSI_MULTISIG_NOT_FOUND && sig == NULL);

	KSI_DataHash_free(hsh);
	KSI_MultiSignature_free(ms);
	KSI_Signature_free(sig);
}
Example #22
0
int KSI_HMAC_create(KSI_CTX *ctx, KSI_HashAlgorithm algo_id, const char *key, const unsigned char *data, size_t data_len, KSI_DataHash **hmac) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_HmacHasher *hasher = NULL;
	KSI_DataHash *tmp_hmac = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || hmac == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	res = KSI_HmacHasher_open(ctx, algo_id, key, &hasher);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_HmacHasher_add(hasher, data, data_len);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_HmacHasher_close(hasher, &tmp_hmac);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	*hmac = tmp_hmac;
	tmp_hmac = NULL;
	res = KSI_OK;

cleanup:

	KSI_DataHash_free(tmp_hmac);
	KSI_HmacHasher_free(hasher);

	return res;
}
static void testFindPublicationByPubStr(CuTest *tc) {
	static const char publication[] = "AAAAAA-CTJR3I-AANBWU-RY76YF-7TH2M5-KGEZVA-WLLRGD-3GKYBG-AM5WWV-4MCLSP-XPRDDI-UFMHBA";
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_PublicationRecord *pubRec = NULL;
	KSI_PublicationData *pub = NULL;
	KSI_DataHash *pubHsh = NULL;
	KSI_Integer *pubTime = NULL;
	KSI_DataHash *expHsh = NULL;
	unsigned char buf[0xff];
	unsigned len;

	KSI_ERR_clearErrors(ctx);

	res = KSI_receivePublicationsFile(ctx, &pubFile);
	CuAssert(tc, "Unable to get publications file.", res == KSI_OK && pubFile != NULL);

	res = KSI_PublicationsFile_getPublicationDataByPublicationString(pubFile, publication, &pubRec);
	CuAssert(tc, "Unable to get publication record by publication string.", res == KSI_OK && pubRec != NULL);

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

	res = KSI_PublicationData_getImprint(pub, &pubHsh);
	CuAssert(tc, "Unable to get published hash", res == KSI_OK && pubHsh != NULL);

	res = KSI_PublicationData_getTime(pub, &pubTime);
	CuAssert(tc, "Unable to get publication time.", res == KSI_OK && pubTime != NULL);

	KSITest_decodeHexStr("01a1b5238ffb05fccfa67546266a0b2d7130f6656026033b6b578c12e4fbbe231a", buf, sizeof(buf), &len);
	res = KSI_DataHash_fromImprint(ctx, buf, len, &expHsh);
	CuAssert(tc, "Unable to get data hash from imprint.", res == KSI_OK && expHsh != NULL);

	CuAssert(tc, "Publication hash mismatch.", KSI_DataHash_equals(expHsh, pubHsh));
	CuAssert(tc, "Publication time mismatch", KSI_Integer_equalsUInt(pubTime, 1397520000));

	KSI_DataHash_free(expHsh);

}
Example #24
0
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;
}
Example #25
0
int KSI_DataHasher_close(KSI_DataHasher *hasher, KSI_DataHash **data_hash) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_DataHash *hsh = NULL;

	if (hasher == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}
	KSI_ERR_clearErrors(hasher->ctx);

	hsh = KSI_new(KSI_DataHash);
	if (hsh == NULL) {
		KSI_pushError(hasher->ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}
	hsh->ref = 1;
	hsh->ctx = hasher->ctx;

	res = hasher->closeExisting(hasher, hsh);
	if (res != KSI_OK) {
		KSI_pushError(hasher->ctx, res, NULL);
		goto cleanup;
	}


	if (data_hash != NULL) {
		*data_hash = hsh;
		hsh = NULL;
	}

	res = KSI_OK;

cleanup:

	KSI_DataHash_free(hsh);

	return res;

}
Example #26
0
static void testExtractingSingleLegacy(CuTest* tc) {
	int res;
	KSI_Signature *sig = NULL;
	KSI_MultiSignature *ms = NULL;
	KSI_DataHash *hsh = NULL;


	KSI_ERR_clearErrors(ctx);

	res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-legacy-sig-2014-06.gtts.ksig"), &sig);
	CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL);

	res = KSI_Signature_getDocumentHash(sig, &hsh);
	CuAssert(tc, "Unable to get signed hash value.", res == KSI_OK && hsh != NULL);

	KSI_DataHash_ref(hsh);

	res = KSI_MultiSignature_new(ctx, &ms);
	CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL);

	res = KSI_MultiSignature_add(ms, sig);
	CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK);

	KSI_Signature_free(sig);
	sig = NULL;

	res = KSI_MultiSignature_get(ms, hsh, &sig);
	CuAssert(tc, "Unable to extract signature from multi signature container.", res == KSI_OK && sig != NULL);

	res = KSI_verifySignature(ctx, sig);
	CuAssert(tc, "Unable to verify extracted signature.", res == KSI_OK);

	KSI_DataHash_free(hsh);
	KSI_MultiSignature_free(ms);
	KSI_Signature_free(sig);
}
Example #27
0
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;
}
Example #28
0
int KSI_PublicationData_fromBase32(KSI_CTX *ctx, const char *publication, KSI_PublicationData **published_data) {
	int res = KSI_UNKNOWN_ERROR;
	unsigned char *binary_publication = NULL;
	size_t binary_publication_length;
	KSI_PublicationData *tmp_published_data = NULL;
	unsigned i;
	unsigned long tmp_ulong;
	KSI_uint64_t tmp_uint64;
	KSI_HashAlgorithm algo_id;
	size_t hash_size;
	KSI_DataHash *pubHash = NULL;
	KSI_Integer *pubTime = NULL;

	KSI_ERR_clearErrors(ctx);

	if (ctx == NULL || publication == NULL || published_data == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}


	res = KSI_base32Decode(publication, &binary_publication, &binary_publication_length);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	if (binary_publication_length < 13) {
		res = KSI_INVALID_FORMAT;
		goto cleanup;
	}

	tmp_ulong = 0;
	for (i = 0; i < 4; ++i) {
		tmp_ulong <<= 8;
		tmp_ulong |= binary_publication[binary_publication_length - 4 + i];
	}

	if (KSI_crc32(binary_publication, binary_publication_length - 4, 0) !=
			tmp_ulong) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "CRC mismatch.");
		goto cleanup;
	}

	res = KSI_PublicationData_new(ctx, &tmp_published_data);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	tmp_uint64 = 0;
	for (i = 0; i < 8; ++i) {
		tmp_uint64 <<= 8;
		tmp_uint64 |= binary_publication[i];
	}

	res = KSI_Integer_new(ctx, tmp_uint64, &pubTime);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_PublicationData_setTime(tmp_published_data, pubTime);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	pubTime = NULL;


	algo_id = binary_publication[8];
	if (!KSI_isHashAlgorithmSupported(algo_id)) {
		KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, NULL);
		goto cleanup;
	}

	hash_size = KSI_getHashLength(algo_id);
	if (binary_publication_length != 8 + 1 + hash_size + 4) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Hash algorithm length mismatch.");
		goto cleanup;
	}

	res = KSI_DataHash_fromImprint(ctx, binary_publication + 8, hash_size + 1, &pubHash);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_PublicationData_setImprint(tmp_published_data, pubHash);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	pubHash = NULL;

	*published_data = tmp_published_data;
	tmp_published_data = NULL;

	res = KSI_OK;

cleanup:
	KSI_Integer_free(pubTime);
	KSI_DataHash_free(pubHash);
	KSI_free(binary_publication);
	KSI_PublicationData_free(tmp_published_data);

	return res;
}
static void testFindPublicationByTime(CuTest *tc) {
	int res;
	KSI_PublicationsFile *pubFile = NULL;
	KSI_PublicationRecord *pubRec = NULL;
	KSI_PublicationData *pub = NULL;
	KSI_DataHash *pubHsh = NULL;
	KSI_Integer *pubTime = NULL;
	KSI_DataHash *expHsh = NULL;
	KSI_LIST(KSI_Utf8String) *pubRefList = NULL;
	unsigned char buf[0xff];
	size_t len;
	KSI_CTX *ctx = NULL;

	res = KSITest_CTX_clone(&ctx);
	CuAssert(tc, "Unable to create KSI context.", res == KSI_OK && ctx != NULL);

	res = KSITest_setDefaultPubfileAndVerInfo(ctx);
	CuAssert(tc, "Unable to set default values to context.", res == KSI_OK);

	KSI_ERR_clearErrors(ctx);

	res = KSI_CTX_setPublicationUrl(ctx, getFullResourcePathUri(TEST_PUBLICATIONS_FILE));
	CuAssert(tc, "Unable to set pubfile URI.", res == KSI_OK);

	res = KSI_receivePublicationsFile(ctx, &pubFile);
	CuAssert(tc, "Unable to get publications file.", res == KSI_OK && pubFile != NULL);

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

	res = KSI_Integer_new(ctx, 1397520000, &pubTime);
	CuAssert(tc, "Unable to create ksi integer object.", res == KSI_OK && pubTime != NULL);

	res = KSI_PublicationsFile_getPublicationDataByTime(pubFile, pubTime, &pubRec);
	CuAssert(tc, "Unable to get publication record by publication date.", res == KSI_OK && pubRec != NULL);

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

	res = KSI_PublicationData_getImprint(pub, &pubHsh);
	CuAssert(tc, "Unable to get published hash", res == KSI_OK && pubHsh != NULL);

	KSI_Integer_free(pubTime);
	pubTime = NULL;

	res = KSI_PublicationData_getTime(pub, &pubTime);
	CuAssert(tc, "Unable to get publication time.", res == KSI_OK && pubTime != NULL);

	KSITest_decodeHexStr("01a1b5238ffb05fccfa67546266a0b2d7130f6656026033b6b578c12e4fbbe231a", buf, sizeof(buf), &len);
	res = KSI_DataHash_fromImprint(ctx, buf, len, &expHsh);
	CuAssert(tc, "Unable to get datahash from imprint", res == KSI_OK && expHsh != NULL);

	CuAssert(tc, "Publication hash mismatch.", KSI_DataHash_equals(expHsh, pubHsh));
	CuAssert(tc, "Publication time mismatch", KSI_Integer_equalsUInt(pubTime, 1397520000));

	res = KSI_PublicationRecord_getPublicationRefList(pubRec, &pubRefList);
	CuAssert(tc, "Unable to get publications ref list", res == KSI_OK && pubRefList != NULL);

	KSI_DataHash_free(expHsh);
	KSI_PublicationsFile_free(pubFile);
	KSI_CTX_free(ctx);
}
Example #30
0
int main(int argc, char **argv) {
	KSI_CTX *ksi = NULL;
	int res = KSI_UNKNOWN_ERROR;

	FILE *in = NULL;
	FILE *out = NULL;

	KSI_DataHasher *hsr = NULL;
	KSI_DataHash *hsh = NULL;
	KSI_Signature *sign = NULL;

	unsigned char *raw = NULL;
	unsigned raw_len;

	unsigned char buf[1024];
	unsigned buf_len;

	char *signerIdentity = NULL;

	FILE *logFile = NULL;

	/* Handle command line parameters */
	/* Handle command line parameters */
	if (argc != 7) {
		fprintf(stderr, "Usage:\n"
				"  %s <in-data-file> <out-sign-file> <aggregator-uri> <user> <pass> <pub-file url | -> \n", argv[0]);
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	/* Input file */
	in = fopen(argv[1], "rb");
	if (in == NULL) {
		fprintf(stderr, "Unable to open input file '%s'\n", argv[1]);
		res = KSI_IO_ERROR;
		goto cleanup;
	}

	/* Create new KSI context for this thread. */
	res = KSI_CTX_new(&ksi);
	if (res != KSI_OK) {
		fprintf(stderr, "Unable to create context.\n");
		goto cleanup;
	}

	logFile = fopen("ksi_sign.log", "w");
	if (logFile == NULL) {
		fprintf(stderr, "Unable to open log file.\n");
	}

	KSI_CTX_setLoggerCallback(ksi, KSI_LOG_StreamLogger, logFile);
	KSI_CTX_setLogLevel(ksi, KSI_LOG_DEBUG);

	KSI_LOG_info(ksi, "Using KSI version: '%s'", KSI_getVersion());

	res = KSI_CTX_setAggregator(ksi, argv[3], argv[4], argv[5]);
	if (res != KSI_OK) goto cleanup;

	/* Check publications file url. */
	if (strncmp("-", argv[6], 1)) {
		res = KSI_CTX_setPublicationUrl(ksi, argv[6]);
		if (res != KSI_OK) {
			fprintf(stderr, "Unable to set publications file url.\n");
			goto cleanup;
		}
	}

	/* Create a data hasher using default algorithm. */
	res = KSI_DataHasher_open(ksi, KSI_getHashAlgorithmByName("default"), &hsr);
	if (res != KSI_OK) {
		fprintf(stderr, "Unable to create hasher.\n");
		goto cleanup;
	}

	/* Read the input file and calculate the hash of its contents. */
	while (!feof(in)) {
		buf_len = (unsigned)fread(buf, 1, sizeof(buf), in);

		/* Add  next block to the calculation. */
		res = KSI_DataHasher_add(hsr, buf, buf_len);
		if (res != KSI_OK) {
			fprintf(stderr, "Unable to add data to hasher.\n");
			goto cleanup;
		}
	}

	/* Close the data hasher and retreive the data hash. */
	res = KSI_DataHasher_close(hsr, &hsh);
	if (res != KSI_OK) {
		fprintf(stderr, "Unable to create hash.\n");
		goto cleanup;
	}

	/* Sign the data hash. */
	res = KSI_createSignature(ksi, hsh, &sign);
	if (res != KSI_OK) {
		fprintf(stderr, "Unable to sign %d.\n", res);
		goto cleanup;
	}

	res = KSI_Signature_verify(sign, ksi);
	if (res != KSI_OK) {
		fprintf(stderr, "Failed to verify signature.\n");
		goto cleanup;
	}

	/* Output the signer id */
	res = KSI_Signature_getSignerIdentity(sign, &signerIdentity);
	if (res == KSI_OK) {
		printf("Signer id: %s\n", signerIdentity);
	} else {
		fprintf(stderr, "Unable to extract signer identity.\n");
	}
    
	/* Serialize the signature. */
	res = KSI_Signature_serialize(sign, &raw, &raw_len);
	if (res != KSI_OK) {
		fprintf(stderr, "Unable to serialize signature.");
		goto cleanup;
	}

	/* Output file */
	out = fopen(argv[2], "wb");
	if (out == NULL) {
		fprintf(stderr, "Unable to open input file '%s'\n", argv[2]);
		res = KSI_IO_ERROR;
		goto cleanup;
	}

	/* Write the signature file. */
	if (!fwrite(raw, 1, raw_len, out)) {
		fprintf(stderr, "Unable to write output file.\n");
		res = KSI_IO_ERROR;
		goto cleanup;
	}

	/* Only print message when signature output is not stdout. */
	if (out != NULL) {
		printf("Signature saved.\n");
	}

	res = KSI_OK;

cleanup:

	if (logFile != NULL) fclose(logFile);

	if (res != KSI_OK && ksi != NULL) {
		KSI_ERR_statusDump(ksi, stderr);
	}

	if (in != NULL) fclose(in);
	if (out != NULL) fclose(out);

	KSI_free(signerIdentity);

	KSI_Signature_free(sign);
	KSI_DataHash_free(hsh);
	KSI_DataHasher_free(hsr);

	KSI_free(raw);

	KSI_CTX_free(ksi);

	return res;

}