示例#1
0
int KSI_PublicationsFile_getLatestPublication(const KSI_PublicationsFile *trust, const KSI_Integer *pubTime, KSI_PublicationRecord **pubRec) {
	int res;
	size_t i;
	KSI_PublicationRecord *result = NULL;
	KSI_Integer *result_tm = NULL;

	if (trust == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	KSI_ERR_clearErrors(trust->ctx);

	if (pubRec == NULL) {
		KSI_pushError(trust->ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}


	for (i = 0; i < KSI_PublicationRecordList_length(trust->publications); i++) {
		KSI_PublicationRecord *pr = NULL;
		KSI_PublicationData *pd = NULL;
		KSI_Integer *tm = NULL;

		res = KSI_PublicationRecordList_elementAt(trust->publications, i, &pr);
		if (res != KSI_OK) {
			KSI_pushError(trust->ctx, res, NULL);
			goto cleanup;
		}

		res = KSI_PublicationRecord_getPublishedData(pr, &pd);
		if (res != KSI_OK) {
			KSI_pushError(trust->ctx, res, NULL);
			goto cleanup;
		}

		res = KSI_PublicationData_getTime(pd, &tm);
		if (res != KSI_OK) {
			KSI_pushError(trust->ctx, res, NULL);
			goto cleanup;
		}

		/* Check if current publication time is after given time. */
		if (pubTime == NULL || KSI_Integer_compare(pubTime, tm) <= 0) {
			/* Check if current publication time is after the latest so far. */
			if (result_tm == NULL || KSI_Integer_compare(result_tm, tm) <= 0) {
				result = pr;
				result_tm = tm;
			}
		}

		KSI_nofree(tm);
		KSI_nofree(pd);
	}

	*pubRec = result;

	res = KSI_OK;

cleanup:

	KSI_nofree(result);
	KSI_nofree(result_tm);

	return res;
}
示例#2
0
static int verifyPublicationWithPubString(KSI_CTX *ctx, KSI_Signature *sig) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_VerificationStep step = KSI_VERIFY_PUBLICATION_WITH_PUBSTRING;
	KSI_VerificationResult *info = &sig->verificationResult;
	KSI_Integer *time1 = NULL;
	KSI_Integer *time2 = NULL;
	KSI_DataHash *hsh1 = NULL;
	KSI_DataHash *hsh2 = NULL;


	if (sig->publication == NULL || sig->verificationResult.useUserPublication == false) {
		res = KSI_OK;
		goto cleanup;
	}


	KSI_LOG_info(ctx, "Verifying publication with publication string");

	if (sig->verificationResult.userPublication == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	res = KSI_PublicationData_getTime(sig->verificationResult.userPublication, &time1);
	if (res != KSI_OK) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	res = KSI_PublicationData_getImprint(sig->verificationResult.userPublication, &hsh1);
	if (res != KSI_OK) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	res = KSI_PublicationData_getTime(sig->publication->publishedData, &time2);
	if (res != KSI_OK) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	res = KSI_PublicationData_getImprint(sig->publication->publishedData, &hsh2);
	if (res != KSI_OK) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	if (KSI_Integer_compare(time1, time2) != 0) {
		KSI_LOG_debug(ctx, "Publication time from publication record:", time2);
		KSI_LOG_debug(ctx, "Publication time from user publication  :", time1);
		res = KSI_VerificationResult_addFailure(info, step, "Publication not trusted.");
		goto cleanup;
	}

	if (KSI_DataHash_equals(hsh1, hsh2) != 1) {
		KSI_LOG_logDataHash(ctx, KSI_LOG_DEBUG, "Root hash from publication record:", hsh2);
		KSI_LOG_logDataHash(ctx, KSI_LOG_DEBUG, "Root hash from user publication:", hsh1);
		res = KSI_VerificationResult_addFailure(info, step, "Publication not trusted.");
		goto cleanup;
	}

	res = KSI_VerificationResult_addSuccess(info, step, "Publication trusted.");


cleanup:

	return res;
}
示例#3
0
/**
 * This function extends the signature to the given publication.
 * \param[in]	sig			Initial signature.
 * \param[in]	pubStr		Null-terminated c string of the publication.
 * \param[out]	ext			Pointer to the receiving pointer to the extended signature.
 * \return Returns KSI_OK if successful.
 */
static int extendToPublication(KSI_Signature *sig, const char *pubStr, KSI_Signature **ext) {
	int res = KSI_UNKNOWN_ERROR;

	/* Only the published data. */
	KSI_PublicationData *pubData = NULL;
	/* Published data and the references to the actual publications. */
	KSI_PublicationRecord *pubRec = NULL;

	/* Publication time. */
	KSI_Integer *pubTime = NULL;
	/* Signature signing time. */
	KSI_Integer *signTime = NULL;
	/* Parse the publications string. */
	res = KSI_PublicationData_fromBase32(ksi, pubStr, &pubData);
	if (res != KSI_OK) {
		fprintf(stderr, "Invalid publication: '%s'\n", pubStr);
		goto cleanup;
	}

	/* Verify the publication is newer than the signature. */
    res = KSI_Signature_getSigningTime(sig, &signTime);
	if (res != KSI_OK) goto cleanup;

	res = KSI_PublicationData_getTime(pubData, &pubTime);
	if (res != KSI_OK) goto cleanup;

	if (KSI_Integer_compare(signTime, pubTime) > 0) {
		fprintf(stderr, "Signature created after publication.\n");
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	/* Create a publication record. */
	res = KSI_PublicationRecord_new(ksi, &pubRec);
	if (res != KSI_OK) goto cleanup;

	/* Set the published data value. */
	res = KSI_PublicationRecord_setPublishedData(pubRec, pubData);
	if (res != KSI_OK) goto cleanup;

	/* The pointer will be free by KSI_PublicatioinRecord_free. */
	pubData = NULL;

	/* NB! If the user wants to store the extended signature, some publication references should
 	 * be added to the publication reference. As we are going to discard the signature after
 	 * verification, the references are not important. */

	/* Extend the signature to the publication. */
	res = KSI_Signature_extend(sig, ksi, pubRec, ext);
	if (res != KSI_OK) {
		fprintf(stderr, "Unable to to extend the signature to the given publication: '%s'\n", pubStr);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	/* We can cleanup the values. */
	KSI_PublicationData_free(pubData);
	KSI_PublicationRecord_free(pubRec);

	return res;
}
示例#4
0
/*TODO: check chain index verification*/
static int rfc3161_verify(const KSI_Signature *sig) {
	int res;
	KSI_CTX *ctx = NULL;
	KSI_RFC3161 *rfc3161 = NULL;
	KSI_AggregationHashChainList *aggreChain = NULL;
	KSI_AggregationHashChain *firstChain = NULL;
	unsigned i;


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


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

	aggreChain = sig->aggregationChainList;
	if (aggreChain == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_SIGNATURE, "Aggregation chain is missing.");
		goto cleanup;
	}

	res = KSI_AggregationHashChainList_elementAt(aggreChain, 0, &firstChain);
	if (res != KSI_OK || firstChain == NULL) {
		KSI_pushError(ctx, res != KSI_OK ? res : (res = KSI_INVALID_STATE), NULL);
		goto cleanup;
	}

	if (KSI_Integer_compare(firstChain->aggregationTime, rfc3161->aggregationTime) != 0) {
		KSI_LOG_debug(ctx, "Signatures aggregation time: %i.", KSI_Integer_getUInt64(firstChain->aggregationTime));
		KSI_LOG_debug(ctx, "RFC 3161 aggregation time:   %i.", KSI_Integer_getUInt64(rfc3161->aggregationTime));
		KSI_pushError(ctx, res = KSI_VERIFICATION_FAILURE, "Aggregation chain and RFC 3161 aggregation time mismatch.");
		goto cleanup;
	}

	if (KSI_IntegerList_length(firstChain->chainIndex) != KSI_IntegerList_length(rfc3161->chainIndex)) {
		KSI_LOG_debug(ctx, "Aggregation chain and RFC 3161 chain index mismatch.", KSI_IntegerList_length(firstChain->chainIndex));
		KSI_LOG_debug(ctx, "Signatures chain index length: %i.", KSI_IntegerList_length(firstChain->chainIndex));
		KSI_LOG_debug(ctx, "RFC 3161 chain index length:   %i.", KSI_IntegerList_length(rfc3161->chainIndex));
	}else {
		for (i = 0; i < KSI_IntegerList_length(firstChain->chainIndex); i++){
			KSI_Integer *ch1 = NULL;
			KSI_Integer *ch2 = NULL;

			res = KSI_IntegerList_elementAt(firstChain->chainIndex, i, &ch1);
			if (res != KSI_OK) {
				KSI_pushError(ctx, res, NULL);
				goto cleanup;
			}

			res = KSI_IntegerList_elementAt(rfc3161->chainIndex, i, &ch2);
			if (res != KSI_OK) {
				KSI_pushError(ctx, res, NULL);
				goto cleanup;
			}

			if (KSI_Integer_compare(ch1, ch2) != 0) {
				KSI_LOG_debug(ctx, "Aggregation chain and RFC 3161 chain index mismatch.", KSI_IntegerList_length(firstChain->chainIndex));
				break;
			}
		}
	}


	res = KSI_OK;

cleanup:

	return res;
}